【问题标题】:Find node recursively in xml document在xml文档中递归查找节点
【发布时间】:2017-04-06 06:48:52
【问题描述】:
<TestSuite name="TestSuite1">
  <TestCase name="TestCase1" UID="1" State="1" DataSourceId="1">
    <TestModule name="Recording1" State="Checked" UID="1">
    </TestModule>
    <TestCase name="TestCase3" UID="bde575e2-74dd-4b5b-9d92-c12cc7e6777d" State="Checked" DataSourceId="" />
  </TestCase>
  <TestCase name="TestCase2" UID="06a4df3b-f072-4f70-a5c3-f0f2ea95654c" State="Checked" DataSourceId="" />
  <TestModule name="ds" State="Checked" UID="16b175a7-b286-484d-ba9a-2a5c9f8dd0fc" />
  <TestModule name="hh" State="Checked" UID="581f5d85-a777-483b-9b5d-ae2830302878" />
</TestSuite>

XmlNode rootNode = xDoc.SelectSingleNode("/TestSuite");
        string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
        XmlNode l_objXmlNode = null;
        foreach (XmlNode node in rootNode.ChildNodes)
        {
            l_objXmlNode = ProcesNode(node, s);
            if (l_objXmlNode != null)
                break;
        }

    private static XmlNode ProcesNode(XmlNode node, string l_selectedNodeUID)
    {
        XmlNode l_objXmlNode = null;
        if (!node.HasChildNodes
            || ((node.ChildNodes.Count == 1) && (node.FirstChild is System.Xml.XmlText)))
        {
            if (node.Attributes["UID"] != null && node.Attributes["UID"].Value == l_selectedNodeUID)
            {
                l_objXmlNode = node;
                return l_objXmlNode;    
            }
        }
        else
        {
            foreach (XmlNode child in node.ChildNodes)
            {
                if (child.Attributes["UID"] != null && child.Attributes["UID"].Value == l_selectedNodeUID)
                {
                    l_objXmlNode = child;
                    break;               
                }
                else
                {
                    return ProcesNode(child, l_selectedNodeUID);
                }
            }
        }

        return l_objXmlNode;
    }'

我必须从具有 UID="value" 的 xml 文件中找到最深的子节点,因为我在上面编写了递归代码,但 l_objXmlNode 总是给我空值。我必须从具有 UID="value 的 xml 文件中找到最深的子节点" 因为我在上面写了递归代码,但 l_objXmlNode 总是给我空值。

【问题讨论】:

  • 为什么不使用 LINQ for XML?如果我理解,您想找到 UID 属性的“所有”值。对吗?
  • 对我应该如何为 Linq to Xml 编码
  • 还有一点,string s = "29239699-6dbc-4c38-aaef-bb5546258f83";没有这个值的 UID 会给你 NULL
  • 我已经更正了字符串的值,但仍然给出 null
  • 正如@A3006 所说,使用 LINQ to XML,但我不明白“最深子节点”的含义,查看您的 XML 我可以假设,您可以找到一组节点,并且他们所有人都会有相同的深度,不是吗?

标签: c# xml xml-parsing


【解决方案1】:

您可以使用 XPath 表达式在 XML 文档中的任何位置查找具有UID 属性等于某个值的元素:

....
string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
XmlNode l_objXmlNode = xDoc.SelectSingleNode(String.Format("//*[@UID='{0}']", s));

或者使用 LINQ-to-XML :

XDocument doc = XDocument.Load("path to your XML file");
string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
XElement l_objXmlNode = doc.Descendants().FirstOrDefault(o => (string)o.Attribute("UID") == s);

【讨论】:

  • 这将始终只选择一个元素。
  • 如何检查节点是否有UID标签
  • @John 你没有回答是你的 XML 中唯一的 UID 值吗?
  • @John 我相信你问这个是因为你得到 ORNSTAI (obejct Ref....) 错误。为此,在 LINQ to XML 中使用 (string)nodes.Attribute("UID") 而不是 .value 应该可以解决您的问题。如果您使用的是 C#6,您可以选择 .?运算符检查 NULL
  • 如果 UID 是唯一的,@har07 上面的代码比我在下面写的更有意义。
【解决方案2】:

试试这个……

public static void SearchNodes()
        {
            XDocument doc = XDocument.Load(@"D:\\Test\\Test2.xml");

            var v = from nodes in doc.Descendants("TestCase")
                    where nodes.Attribute("UID").Value == "06a4df3b-f072-4f70-a5c3-f0f2ea95654c"
                    select nodes;

            foreach (var item in v)
            {
                Console.Write(item);    
            }

        }

你会得到以下输出

<TestCase name="TestCase2" UID="06a4df3b-f072-4f70-a5c3-f0f2ea95654c" State="Che
cked" DataSourceId="" />

您可以将预期值作为参数传递给 SearchNodes 函数。

【讨论】:

  • @A306 如何从 XmlDocument 中获取所有 TestModule 节点
  • 去掉where子句,用TestModule替换TestCase,就可以得到所有的TestModule节点了。
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多