[英]How to select multiple XML child nodes with similar names
这是我的XML文件:
<hashtable>
<entry>
<string>krishna.com</string>
<hashtable>
<entry>
<string>status</string>
<string>available</string>
</entry>
<entry>
<string>classkey</string>
<string>domcno</string>
</entry>
</hashtable>
</entry>
<entry>
<string>krishna.net</string>
<hashtable>
<entry>
<string>status</string>
<string>regthroughothers</string>
</entry>
<entry>
<string>classkey</string>
<string>dotnet</string>
</entry>
</hashtable>
</entry>
</hashtable>
我想通过krishna.com(node:hashtable / entry / string)找到可用的状态(节点:hashtable / entry / hashtable / entry / string)。
在这里,我的困难是有太多类似的节点名称,例如string
和entry
,所以我如何通过检查status
(字符串节点)和available
status
(字符串节点)来检查krishna.com和krishna.net域的status
是否可用。
你可以尝试这样的事情
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("Path to your .xml file");
XmlNodeList nodeList = xmlDoc.SelectNodes("//entry/string");
现在,您可以编写自己的代码来获取nodeList中的信息;
这是为您提供的XPath解决方案。
using System;
using System.Xml.Linq;
using System.Xml.XPath;
static string GetStatus(XDocument doc, string nodeName)
{
//The first xpath translates to: "Select the <hashtable> element that immediately
// follows the <string> element with a value of nodeName."
//The second xpath selects the <string> element that immediately follows another <string>
// element with a value of 'status'. This selected element is a descendant of the
// <hashtable> element that was selected first.
XElement status = doc.XPathSelectElement("//hashtable[preceding-sibling::string = '" + nodeName + "']")
.XPathSelectElement("descendant::string[preceding-sibling::string = 'status']");
return status.Value;
}
使用此方法的原因很合理:
XDocument doc = XDocument.Load("File_path_to_XML.xml");
string status = GetStatus(doc, "krishna.com");
// status == "available"
string status2 = GetStatus(doc, "krishna.net");
// status2 == "regthroughothers"
您可以使用LINQ to XML来搜索满足指定条件的节点。 此示例选择在其子“哈希表”节点下包含“状态”和“可用”子节点的第一级“入口”节点,如示例结构所示:
XDocument doc;
using (FileStream fs = new FileStream("XMLFile1.xml", FileMode.Open))
{
doc = XDocument.Load(fs);
}
string[] elms = doc.Element("hashtable").Elements("entry").Where(elm =>
elm.Element("hashtable").Element("entry").Elements("string").First().Value == "status" &&
elm.Element("hashtable").Element("entry").Elements("string").Skip(1).First().Value == "available")
.Select(elm => elm.Element("string").Value).ToArray();
如果您的文件结构与您提供的示例不同,则需要相应地修改查询
您可能需要类似:
//hashtable/entry/string[1][text() = 'krishna.com']"/../hastable/entry/string[1][text() = 'status']"/../string[2][text() = 'available']
未经测试,但需要注意以下几点:
//
表示从任何节点开始 A/B
表示元素A下的元素B A/B[1]
表示元素A下的第一个元素B A[text() = 'foo']
表示元素A,其中包含foo作为文本值 ..
表示父节点 如果这样做不起作用,则始终可以先找到krishna.com的hashtable
,然后在entry
节点下的第一个位置中找到包含值“ status”的string
节点,然后确保仅该string
节点的同级对象另一个包含“可用”的string
节点。
这是我的想法:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("your_xml_file.xml");
XmlElement root = xmlDoc.DocumentElement;
string query = "child::entry/child::string[following-sibling::*/descendant::string[text()='available']]";
XmlNodeList nodes = root.SelectNodes(query);
foreach (XmlNode node in nodes)
{
Console.WriteLine(node.InnerText);
}
//Result
krishna.com
它将显示“可用”域的名称。
在查询字符串中,“ child :: entry”将选择root的子级,称为“ entry”。 (不是后代)。 因此路径为“ / hashtable / entry”。
接下来,对于每个“入口”节点,它将选择包含域名的“字符串”子级。 在此步骤中,它使用表达式选择“可用”一个。 现在,路径变为“ / hashtable / entry / string”。 在表达式中,首先它将选择以下所有兄弟姐妹,并且在您的xml中,仅“ hashtable”满足条件。 最后,对于以下所有兄弟姐妹,我们检查其后代,如果后代的名称为“ string”且其内部文本为“ available”,则将选择当前域节点。
希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.