Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
3 / 3 / 1
Регистрация: 29.08.2012
Сообщений: 24
1
.NET 4.x

Create XML file with XPath, using XDocument

07.05.2014, 20:13. Просмотров 1371. Ответов 2
Метки нет (Все метки)


Здравствуйте! (тема на англ, т.к. форум не позволяет использовать понятное русское название)

Требуется создать XML файл с помощью XPath.

В интернете нашел следующую функцию, которая создает элементы, но получается добавить элемент в уже существующий.

Пример:
XML
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <Window>
    <Topmost>true</Topmost>
    <!-- сюда нельзя больше ничего добавить -->
  </Window>
<!-- сюда нельзя больше ничего добавить -->
</Settings>
Происходит это потому, что в функции каждый раз создается новый элемент с уже существующими. Как исправить не знаю, бьюсь второй день.

Вот функция:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
private static XNode CreateNodeFromXPath(XNode elem, string xpath)
        {
            // Create a new Regex object
            var r = new Regex(@"/+([a-zA-Z0-2\.\-]+)(\[@([a-zA-Z0-2\.\-]+)='([^']*)'\])?|/@([a-zA-Z0-2\.\-]+)");
 
            xpath = xpath.Replace("\"", "'");
            // Find matches
            var m = r.Match(xpath);
 
            var currentNode = elem;
            var currentPath = new StringBuilder();
 
            while (m.Success)
            {
                var currentXPath = m.Groups[0].Value;    // "/configuration" or "/appSettings" or "/add"
                var elementName = m.Groups[1].Value;     // "configuration" or "appSettings" or "add"
                var filterName = m.Groups[3].Value;      // "" or "key"
                var filterValue = m.Groups[4].Value;     // "" or "name"
                var attributeName = m.Groups[5].Value;   // "" or "value"
 
                var builder = currentPath.Append(currentXPath);
                var relativePath = builder.ToString();
                var newNode = (XNode)elem.XPathSelectElement(relativePath);
 
                if (newNode == null)
                {
                    if (!string.IsNullOrEmpty(attributeName))
                    {
                        ((XElement)currentNode).Attribute(attributeName).Value = "";
                        newNode = (XNode)elem.XPathEvaluate(relativePath);
                    }
                    else if (!string.IsNullOrEmpty(elementName))
                    {
                        var newElem = new XElement(elementName);
                        if (!string.IsNullOrEmpty(filterName))
                        {
                            newElem.Add(new XAttribute(filterName, filterValue));
                        }
 
                        ((XElement)currentNode).Add(newElem);
                        newNode = newElem;
                    }
                    else
                    {
                        throw new FormatException("The given xPath is not supported " + relativePath);
                    }
                }
 
                currentNode = newNode;
                m = m.NextMatch();
            }
Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.05.2014, 20:13
Ответы с готовыми решениями:

LINQ to XML или XPath to XML (выбор одного элемента)
Прошу помощи в LINQ или XPath запросе к XML Вот XML: &lt;manifest...

System.IO.File.Create не работает
Hello Проблема с таким куском кода System.IO.File.Exsist(string path) работает на ура, а...

Удаление файла. File.Create() - File.Delete()
Добрый день! Не нашёл вразумительного ответа на свой вопрос. Создаю файл (File.Create()) и при...

Чтение XML через XDocument и формирование TreeView
Здравствуйте. Хочу считать xml файл и заполнить treeView в C#. using System; using...

__________________
Помогаю в написании студенческих работ здесь.
Записывайтесь на профессиональные курсы С#-разработчиков‌
2
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.05.2014, 23:51 2
FeaRMysLF, имхо ваша проблема в регэкспах. В древовидных структурах вроде XML они бесполезны. Используйте объектную модель, а ля Elements/Descendants.
0
3 / 3 / 1
Регистрация: 29.08.2012
Сообщений: 24
08.05.2014, 00:57  [ТС] 3
Psilon, нет, в них никакой проблемы нет. Просто проблема в том, что каждый раз заново создаются все элементы. Например, вот функция записи:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        /// <summary>
        /// Writes the data to specified node
        /// </summary>
        /// <param name="value">Value to write</param>
        /// <param name="xpath">Node to read from</param>
        public void Write<TValue>(TValue value, string xpath)
        {
            var RootElement = "Settings";
            var tempElement = new XElement(RootElement);
            var tempNode = CreateNodeFromXPath(tempElement, xpath) as XElement;
            tempNode.SetValue(value);
 
            if (_xmlfile.XPathSelectElement(RootElement + xpath) == null)
                _xmlfile.Add(tempElement);
            else
                _xmlfile.XPathSelectElement(RootElement + xpath).SetValue(value);
        }
Write(Topmost, "/Window/Topmost");

Результат:
XML
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <Window>
    <Topmost>true</Topmost>
  </Window>
</Settings>
Но если нужно добавить еще один элемент (пр Taskbar) в Window или в Settings, то выскочит InvalidOperation (неправильная структура файла) - из-за того, что CreateNodeFromXPath создаст элемент с такой структурой:
XML
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <Window>
    <Taskbar>true</Taskbar>
  </Window>
</Settings>
Чтобы это исправить (изменить Write) нужно добавлять элементы напрямую в Settings, Window и прочее.

Все это нужно, т.к. в итоге функция Save (для настроек) очень сильно сокращается и можно сохранять каждое свойство в строку.

Если никто не поможет, то придется использовать обычную модель через XElement.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.05.2014, 00:57

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Create File txt with OpenFileDialog
Интересует это: Команда «Open...» выводит диалоговое окно OpenFileDialog; с его помощью можно...

TFilestream.create [cannot create file]
function bat: string; begin with...

Из List<string> в XDocument XML
Всем добрый день! Дан xml с настройками вида: &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;...

Caused by: android.view.InflateException: Binary XML file line #13: Binary XML file line #13: Error inflating class
Caused by: android.view.InflateException: Binary XML file line #13: Binary XML file line #13: Error...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.