Как найти узел xml

  1. Как найти узел по атрибуту?
  2. Как найти узел по атрибуту и удалить?
  3. Как найти узел по атрибуту и изменить атрибут?

Только без LINQ.

Пример XML-файла.

System.xml
<?xml version="1.0" encoding="utf-8" ?>
<users>
  <user name="Bill Gates">
    <company>Microsoft</company>
    <age>48</age>
  </user>
  <user name="Larry Page">
    <company>Google</company>
    <age>48</age>
  </user>
</users>

ixSci's user avatar

ixSci

23.7k3 золотых знака46 серебряных знаков61 бронзовый знак

задан 11 июл 2015 в 20:38

Антон Рейтаровский's user avatar

3

1.

XmlNodeList nodes = xmlDoc.SelectNodes("//element[@name='value']");

2.

for (int i = nodes.Count - 1; i >= 0; i--)
{ 
    nodes[i].ParentNode.RemoveChild(nodes[i]);
}

3.

XmlNode node = xmlDoc.SelectSingleNode("//element[@name='value']");
node.Attributes[0].Value = newValue;

andreycha's user avatar

andreycha

25k4 золотых знака45 серебряных знаков81 бронзовый знак

ответ дан 11 июл 2015 в 20:52

cpp_user's user avatar

cpp_usercpp_user

1,50310 серебряных знаков16 бронзовых знаков

Let’s say that you have an XmlNode instance called node to start with. Then the following code will give you the last child of the last child of the first child of the great grand parent of that node:

XmlNode wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;

Note that there are so many things that can go wrong with this code. If any of the referenced nodes happen to be null, you have a NullReferenceException coming. So you will want to make a null check at each level:

XmlNode wantedNode;

if (node.ParentNode != null && node.ParentNode.ParentNode != null /* and so on through the full path */)
{
    wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
}

Let’s examine this with a more concrete example. Assume we have the following Xml document:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <greatgrandparent>
    <grandparent>
      <parent id="1">
        <child somevalue="3"></child>
      </parent>
      <parent id="2">
        <child somevalue="4"></child>
        <child somevalue="5"></child>
      </parent>
    </grandparent>
  </greatgrandparent>
</root>

If I understand your question right, if we start from the node <child somevalue="3"></child> we want to navigate to <child somevalue="5"></child>. The code sample above will do that. However, as mentioned, it is prone to giving exceptions if not all expected nodes are present.

Even though you said that you want c# code rather than XPath, in this case I feel that XPath is the way to go. There are a number of ways to solve this. For instance, if the nodes have different tag names (as in my sample document), you can instead do like this:

XmlNode wantedNode = node.SelectSingleNode("ancestor::greatgrandparent/grandparent[position()=1]/parent[position()=last()]/child[position()=last()]");
if (wantedNode != null)
{
    // the path was found
}

This is of course assuming that node is not null, but a valid XmlNode instance.

Breakdown of the XPath expression:

  • ancestor::greatgrandparent -> this will locate any node named “greatgrandparent” that is located anywhere upwards in the hierarchy (so any parent, grand parent and so on)
  • /grandparent[position()=1] -> the first child node named “grandparent”
  • /parent[position()=last()] -> the last child node named “parent”
  • /child[position()=last()] -> the last child node named “child”

If you want to read some about how XPath axes work, there is some information on w3schools.com.

Для выбора узлов и наборов узлов в XML документе XPath использует выражения путей. Узел выбирается следуя по заданному пути или по, так называемым, шагам.

Пример XML документа

Для демонстрации синтаксиса XPath будет использоваться следующий XML документ:


<?xml version="1.0" encoding="UTF-8"?>
<messages>
   <note>
      <heading  date="10/01/2008">Напоминание</heading>
      <body>Отправить письмо!</body>
   </note>
   <note>
      <heading  date="11/01/2008">Re: Напоминание</heading>
      <body>Письмо отправлено</body>
   </note>
</messages>

Выбор узлов

Чтобы выбрать узлы в XML документе, XPath использует выражения пути. Узел выбирается следуя по заданному пути. Наиболее полезные выражения пути:

Выражение Результат
имя_узла Выбирает все узлы с именем “имя_узла”
/ Выбирает от корневого узла
// Выбирает узлы от текущего узла, соответствующего выбору, независимо от их местонахождения
. Выбирает текущий узел
.. Выбирает родителя текущего узла
@ Выбирает атрибуты

В следующей таблице приводятся некоторые выражения XPath, позволяющие сделать некоторые выборки по демонстрационному XML документу:

Выражение XPath Результат
messages Выбирает все узлы с именем “messages”
/messages Выбирает корневой элемент сообщений
Примечание: Если путь начинается с косой черты ( / ), то он всегда представляет абсолютный путь к элементу!
messages/note Выбирает все элементы note, являющиеся потомками элемента messages
//note Выбирает все элементы note независимо от того, где в документе они находятся
messages//note Выбирает все элементы note, являющиеся потомками элемента messages независимо от того, где они находятся от элемента messages
//@date Выбирает все атрибуты с именем date

Предикаты

Предикаты позволяют найти конкретный узел или узел с конкретным значением.

Предикаты всегда заключаются в квадратные скобки.

В следующей таблице приводятся некоторые выражения XPath с предикатами, позволяющие сделать выборки по демонстрационному XML документу:

Выражение XPath Результат
/messages/note[1] Выбирает первый элемент note, который является прямым потомком элемента messages.
Примечание: В IE 5,6,7,8,9 первым узлом будет [0], однако согласно W3C это должен быть [1]. Чтобы решить эту проблему в IE, нужно установить опцию SelectionLanguage в значение XPath.
В JavaScript: xml.setProperty(“SelectionLanguage”,”XPath”);
/messages/note[last()] Выбирает последний элемент note, который является прямым потомком элемента messages.
/messages/note[last()-1] Выбирает предпоследний элемент note, который является прямым потомком элемента messages.
/messages/note[position()<3] Выбирает первые два элемента note, которые являются прямыми потомками элемента messages.
//heading[@date] Выбирает все элементы heading, у которых есть атрибут date
//heading[@date=”10/01/2008″] Выбирает все элементы heading, у которых есть атрибут date со значением “10/01/2008”

Выбор неизвестных заранее узлов

Чтобы найти неизвестные заранее узлы XML документа, XPath позволяет использовать специальные символы.

Спецсимвол Описание
* Соответствует любому узлу элемента
@* Соответствует любому узлу атрибута
node() Соответствует любому узлу любого типа

В следующей таблице приводятся некоторые выражения XPath со спецсимволами, позволяющие сделать выборки по демонстрационному XML документу:

Выражение XPath Результат
/messages/* Выбирает все элементы, которые являются прямыми потомками элемента messages
//* Выбирает все элементы в документе
//heading[@*] Выбирает все элементы heading, у которых есть по крайней мере один атрибут любого типа

Выбор нескольких путей

Использование оператора | в выражении XPath позволяет делать выбор по нескольким путям.

В следующей таблице приводятся некоторые выражения XPath, позволяющие сделать выборки по демонстрационному XML документу:

Выражение XPath Результат
//note/heading | //note/body Выбирает все элементы heading И body из всех элементов note
//heading | //body Выбирает все элементы heading И body во всем документе

С DOM, вы можете получить доступ к любому узлу в документе XML.


Попробуйте сами – Примеры

Приведенные ниже примеры используют XML – файл Books.xml .

Получить доступ к узлу , используя его номер индекса в списке узлов
Используйте getElementsByTagName() метод , чтобы получить третий <title> элемент в “books.xml”

Петля через узлы , используя свойство длины
Используйте свойство длины Переберите все <title> элементы в “books.xml”

См тип узла элемента
Используйте свойство NODETYPE , чтобы получить тип узла корневого элемента в “books.xml” .

Перебор узлов элемента
Используйте свойство NODETYPE для узлов элементов , только в процессе “books.xml” .

Петля через узлы элемента с помощью узла связи
Обработать узлы элемента в Используйте свойство NODETYPE и свойство NextSibling “books.xml” .


Доступ к узлов

Вы можете получить доступ к узлу тремя способами:

1. Используя getElementsByTagName() метод

2. пробегаем по (traversing) дерева узлов.

3. навигации по дереву узлов, используя узел связи.


getElementsByTagName() Метод

getElementsByTagName () возвращает все элементы с указанным именем тега.

Синтаксис

node.getElementsByTagName(“tagname”);

пример

Следующий пример возвращает все <title> элементов под х элементов:

x.getElementsByTagName(“title”);

Обратите внимание , что приведенный выше пример возвращает только <title> элементов под х узла. Для того, чтобы вернуть все <title> элементов в использовании XML – документа:

xmlDoc.getElementsByTagName(“title”);

где xmlDoc является сам документ (document node) .


DOM списка узлов

getElementsByTagName() метод возвращает список узлов. Список узел представляет собой массив узлов.

x = xmlDoc.getElementsByTagName(“title”);

<title> элементы х можно получить по номеру индекса. Чтобы получить доступ к третьей <title> вы можете написать ::

Note: Индекс начинается с 0.

Вы узнаете больше о списках узлов в следующей главе данного руководства.


DOM Список узлов Длина

Свойство длина определяет длину списка узлов (the number of nodes) .

Вы можете перебрать список узлов, используя свойство длины:

пример

var
x = xmlDoc.getElementsByTagName(“title”);

for (i = 0; i <x.length; i++) {
  //
do something for each node
  }

Попробуй сам ”


Типы узлов

documentElement свойство документа XML является корневой узел.

nodeName свойство узла является именем узла.

nodeType свойство узла является тип узла.

Вы узнаете больше о свойствах узла в следующей главе данного руководства.

Попробуй сам


обходе узлов

Следующий код перебирает дочерние узлы, которые также являются узлы элементов, из корневого узла:

пример

txt = “”;
x = xmlDoc.documentElement.childNodes;

for (i = 0; i <x.length; i++)
{
  // Process only element nodes (type 1)
  if (x[i].nodeType == 1) {
   
txt += x[i].nodeName + “<br>”;
  }
}

Попробуй сам ”

Объяснение примера:

  1. Предположим , что вы загрузили ” Books.xml ” в xmlDoc
  2. Получить дочерние узлы корневого элемента (xmlDoc)
  3. Для каждого дочернего узла, проверьте тип узла. Если тип узла “1” это узел элемента
  4. Выходное имя узла, если он является узлом элемента

Перемещение по Узел Связи

Следующий код переходит дерево узлов с помощью узла связи:

пример

x = xmlDoc.getElementsByTagName(“book”)[0];
xlen = x.childNodes.length;
y = x.firstChild;

txt = “”;
for (i = 0; i <xlen; i++)
{
  // Process only element nodes (type 1)
 
if (y.nodeType == 1) {
    txt += y.nodeName + “<br>”;
  }
 
y = y.nextSibling;
}

Попробуй сам ”

Объяснение примера:

  1. Предположим , что вы загрузили ” Books.xml ” в xmlDoc
  2. Получить дочерние узлы первой книги элемента
  3. Установите “y” переменную , чтобы быть первым дочерним узлом первой книги элемента
  4. Для каждого дочернего узла (starting with the first child node “y”) :
  5. Проверьте тип узла. Если тип узла “1” это узел элемента
  6. Выходное имя узла, если он является узлом элемента
  7. Установите “y” переменную , чтобы быть следующим узлом родного брата, и снова запустить через петлю

Добавить комментарий