С#: Получение всех узлов XML-документа

Есть ли простой способ получить все узлы из XML-документа? Мне нужны все node, childnode и т.д., Чтобы проверить, есть ли у них определенные атрибуты.

Или мне придется просканировать документ, запросив его дочерние элементы?

Ответ 1

В LINQ to XML это очень просто:

XDocument doc = XDocument.Load("test.xml"); // Or whatever
var allElements = doc.Descendants();

Итак, чтобы найти все элементы с определенным атрибутом, например:

var matchingElements = doc.Descendants()
                          .Where(x => x.Attribute("foo") != null);

Предполагая, что вам нужны все элементы. Если вы хотите, чтобы все узлы (включая текстовые узлы и т.д., Но не включали атрибуты в виде отдельных узлов), вы использовали бы DescendantNodes().

EDIT: Пространства имен в LINQ to XML хороши. Вы должны использовать:

var matchingElements = doc.Descendants()
                          .Where(x => x.Attribute(XNamespace.Xmlns + "aml") != null);

или для другого пространства имен:

XNamespace ns = "http://some.namespace.uri";

var matchingElements = doc.Descendants()
                          .Where(x => x.Attribute(ns + "foo") != null);

Ответ 2

см. здесь: Итерация через все узлы в файле XML

коротко:

 string xml = @"
    <parent>
      <child>
        <nested />
      </child>
      <child>
        <other>
        </other>
      </child>
    </parent>
    ";

  XmlReader rdr = XmlReader.Create(new System.IO.StringReader(xml));
  while (rdr.Read())
  {
    if (rdr.NodeType == XmlNodeType.Element)
    {
      Console.WriteLine(rdr.LocalName);
    }
  }

Ответ 3

На мой взгляд, самым простым решением является использование XPath. Также это работает, если у вас есть .NET 2:

var testDoc = new XmlDocument();
                testDoc.LoadXml(str);
                var tmp = testDoc.SelectNodes("//*"); // match every element

Ответ 4

XDocument.Descendants вернет вам все узлы в плоском перечислимом.

Ответ 5

Ознакомьтесь с LINQ to XML. Это делает то, что вам нужно.

http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

Вы можете использовать расширение SelectMany, например.

Но если вы хотите проверить значения, вы можете просто использовать LINQ для создания where -statements.

Ответ 6

  protected void Page_Load(object sender, EventArgs e)
  {

            XmlDocument document = new XmlDocument();

            string xmlStr;
            using (var wc = new WebClient())
            {
                xmlStr = wc.DownloadString("test.xml");
            }

            var xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xmlStr);

            XmlNode xnod = xmlDoc.DocumentElement;

           AddWithChildren(xnod, 1);
 }

Ответ 7

public void AddWithChildren(XmlNode xnod, Int32 intLevel) //,XmlDocument xmlDoc
    {  
        List<IEnumerable> item = new List<IEnumerable>();
        XmlNode xnodWorking;
        String strIndent = new string('-', 2 * intLevel);
        String strIndent1 = new string('@', 2 * intLevel);
        if (xnod.NodeType == XmlNodeType.Element)
        {
            item.Add(new ListXML(strIndent + xnod.Name, strIndent + xnod.Name, ""));
            XmlNamedNodeMap mapAttributes = xnod.Attributes;
            foreach (XmlNode xnodAttribute in mapAttributes)
            {
                item.Add(new ListXML(strIndent1 + xnodAttribute.Name, strIndent1 + xnodAttribute.Name, ""));
            }
            if (xnod.HasChildNodes)
            {
                xnodWorking = xnod.FirstChild;
                while (xnodWorking != null)
                {
                    AddWithChildren(xnodWorking, intLevel + 1);
                    xnodWorking = xnodWorking.NextSibling;
                }
            }
        }
    }