Есть ли простой способ получить все узлы из XML-документа? Мне нужны все node, childnode и т.д., Чтобы проверить, есть ли у них определенные атрибуты.
Или мне придется просканировать документ, запросив его дочерние элементы?
Есть ли простой способ получить все узлы из XML-документа? Мне нужны все node, childnode и т.д., Чтобы проверить, есть ли у них определенные атрибуты.
Или мне придется просканировать документ, запросив его дочерние элементы?
В 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);
см. здесь: Итерация через все узлы в файле 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);
}
}
На мой взгляд, самым простым решением является использование XPath. Также это работает, если у вас есть .NET 2:
var testDoc = new XmlDocument();
testDoc.LoadXml(str);
var tmp = testDoc.SelectNodes("//*"); // match every element
XDocument.Descendants вернет вам все узлы в плоском перечислимом.
Ознакомьтесь с LINQ to XML. Это делает то, что вам нужно.
http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx
Вы можете использовать расширение SelectMany
, например.
Но если вы хотите проверить значения, вы можете просто использовать LINQ для создания where
-statements.
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);
}
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;
}
}
}
}