【问题标题】:Get child node attribute value based on parent node attribute value根据父节点属性值获取子节点属性值
【发布时间】:2015-07-01 07:52:44
【问题描述】:

我在下面给出了一个 xml

 <session xmlns="http://test.net/schema/session/1.0" name="test" start="2015-07-01T07:20:31.425Z">

  <download>
    <filename value="/UAT/Incoming/ Status/Archive/8-22-2011 3-20-14 PM306.xml" />
    <result success="false">
      <message>Timeout waiting .</message>
    </result>
  </download>
</session>

仅当 Result 节点值为 false 时,我才想选择 message 节点值。 我不想检查硬编码的父节点,比如节点下载,因为它可能会改变

谁能帮帮我..

【问题讨论】:

标签: c# xml linq linq-to-xml


【解决方案1】:
        XDocument doc = XDocument.Load("your xml file path");
        var result = doc.Elements().
            First(e => e.Name == "download")
        .Elements().First(e => e.Name == "result");
        if (result.Attributes().First(a => a.Name == "success").Value == "false")
            return result.Elements().First(e => e.Name == "message").Value;

【讨论】:

  • 感谢您的回答,但我认为解释您的代码的作用可能会有所帮助!
  • 这很好。但是如果父节点不是恒定的..我的意思是 可能会有像 这样的节点。那么解决方案是什么
【解决方案2】:

这对我有用:

XNamespace ns = XNamespace.Get("http://test.net/schema/session/1.0");

IEnumerable<XElement> failures =
    doc
        .Descendants(ns + "download")
        .Concat(doc.Descendants(ns + "upload"))
        .Elements(ns + "result")
        .Elements(ns + "message")
        .Where(e => e.Parent.Attributes("success").Any(a => !(bool)a));

从你的输入我得到了这个:

【讨论】:

  • 这很好。但是如果父节点不是恒定的..我的意思是在 之外可能有像 这样的节点。那么解决方案是什么
  • @sandeep.mishra - 我添加了上传解决方案。会比这两个多吗?
【解决方案3】:

首先你需要像这样为你的 XML 文件设置命名空间:-

XNamespace ns = "http://test.net/schema/session/1.0";

我将开始研究download 的后代,因为我需要找到包含success 属性(我们要检查其值)的result 元素。因此,一个简单的 where 条件将为我们过滤这些节点,最后我们可以选择 message 节点。

更新:

如果你想像这样搜索下载和上传,你可以使用Concat:-

IEnumerable<XElement> result = xdoc.Descendants(ns + "download")
                                 .Concat(xdoc.Descendants(ns + "upload"))
              .Where(x => x.Element(ns + "result") != null && 
                  (string)x.Element(ns + "result").Attribute("success") == "false")
              .Select(x => x.Element(ns +"result").Element(ns +"message"));

如果结果节点存在与否,我也会通过检查null来检查where子句,否则可能会导致Null引用异常。

【讨论】:

  • 节点下载可能会有所不同,可能是上传。你能建议一种通用的方式吗?
  • @sandeep.mishra - 如果我对你的理解正确,你需要一个Concat,然后你可以上传和下载。检查我的更新。
【解决方案4】:

使用一些 XPath,下面的代码应该可以工作

    string xml = @"<session xmlns=""http://test.net/schema/session/1.0"" name=""test"" start=""2015-07-01T07:20:31.425Z"">    
      <download>
        <filename value=""/UAT/Incoming/ Status/Archive/8-22-2011 3-20-14 PM306.xml"" />
        <result success=""false"">
          <message>Timeout waiting .</message>
        </result>
      </download>
    </session>";

    XmlDocument xdoc  = new XmlDocument();
    xdoc.LoadXml(xml);

    // Here, you load the namespace used in your xml. You'll need it later in your XPath queries
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
    nsmgr.AddNamespace("test", "http://test.net/schema/session/1.0");

    // XPath to select the "result" node whose attribute "success" equals false
    XmlElement xelt = xdoc.DocumentElement.SelectSingleNode("descendant::test:download/test:result[@success=\"false\"]", nsmgr) as XmlElement;

    // return the "message" node
    return xelt.FirstChild as XmlElement;

如前所述,您可以在此链接上找到有关 XPath 表达式的更多详细信息:https://msdn.microsoft.com/en-us/library/d271ytdx%28v=vs.110%29.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    相关资源
    最近更新 更多