【问题标题】:Get child elements of xml based on parent element's value根据父元素的值获取xml的子元素
【发布时间】:2015-09-12 02:37:48
【问题描述】:

我有一个如下所示的 XML 字符串:

<?xml version="1.0" encoding="utf-8"?>
<Report>
  <Version Name="2.0">
    <Note>The meaning of life is 42.</Note>
    <Note>Hitchiker's Guide to the Galaxy</Note>
  </Version>
  <Version Name="2.1">
    <Note>Football is awesome!</Note>
    <Note>Let's go sailing!</Note>
  </Version>
</Report>

我正在尝试将每个版本的信息输出到我的网页。到目前为止,我能够获得版本号,但无法将注释与版本号相关联。这是我所拥有的:

var xml = Client.GetReleaseNotes();

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

var versions = Client.GetUniqueNames(doc.SelectNodes("//Version"));
versions.Reverse();

Client.GetReleaseNotes(); 给了我要解析的 XML 字符串。

public List<string> GetUniqueNames(XmlNodeList nodes)
        {
            List<string> list = new List<string>();
            foreach (XmlNode node in nodes)
            {
                var attr = node.Attributes["Name"] ?? node.Attributes["Title"];
                string name = attr.InnerText;
                if (!list.Contains(name) && name.IndexOf("sample", StringComparison.OrdinalIgnoreCase) == -1)
                    list.Add(name);
            }

            list.Sort();

            return list;
        }

public List<string> GetVersionNotes(XmlNodeList nodes)
        {
            List<string> list = new List<string>();

            foreach (XmlNode node in nodes)
            {
                list.Add(node.Value);
            }

            list.Sort();

            return list;
        }

如下所示,我使用 foreach 循环将版本号输出到屏幕。

<section id="release-notes">
    <div class="container">
        <div class="row">
            <div class="col-lg-12 text-center">
                <h2 class="section-heading">Release Notes</h2>
            </div>
        </div>
        <div class="row">
            @foreach (string version in versions)
            {
                <div class="col-md-4">
                    <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
                        <div class="panel panel-default">
                            <div class="panel-heading" role="tab" id="webHeading">
                                <h4 class="panel-title">
                                    <a role="button" data-toggle="collapse" data-parent="#accordion" href="#webPanel" aria-expanded="true" aria-controls="webPanel">
                                        Version @version
                                    </a>
                                </h4>
                            </div>
                            <div id="webPanel" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="webHeading">
                                <ul class="list-group">
                                    @{
                                        var notes = Client.GetVersionNotes(doc.SelectNodes("//version[@value='" + version + "']/note"));
                                    }

                                    @foreach (string note in notes)
                                    {
                                        <li class="list-group-item">@note</li>
                                    }
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            }
        </div>
    </div>
</section>

然后我继续使用另一个 foreach 循环并尝试获取每个版本的子元素。这样我就可以将笔记与它的版本相关联。我读到您可以使用 SelectNodes 方法根据特定条件(例如父节点的值)获取子节点。这就是促使我创建 var notes = Client.GetVersionNotes(doc.SelectNodes("//version[@value='" + version + "']/note"));

行的原因

但是我仍然无法获得笔记。我究竟做错了什么?有人可以指出我正确的方向吗?

【问题讨论】:

    标签: c# asp.net xml


    【解决方案1】:

    请注意,XPath 中的元素和属性名称是区分大小写的。此外,您的 XPath 中有错误的属性名称(应该是 @Name 而不是 @value)。试试这种方式获取对应的Note元素:

    doc.SelectNodes("//Version[@Name='" + version + "']/Note")
    

    【讨论】:

    • 通过更改您的建议并在版本上将我的 V 大写,现在可以将正确数量的项目添加到列表中,但项目是空白的。
    • 尝试在 GetVersionNotes() 中使用 node.InnerText 代替 oDnode.Value
    【解决方案2】:

    另一个选择是使用 LINQ to XML。

    方法如下:

    var doc = XDocument.Parse(@"<?xml version=""1.0"" encoding=""utf - 8""?>
    <Report>
      <Version Name = ""2.0"">
        <Note>The meaning of life is 42.</Note>
        <Note>Hitchiker's Guide to the Galaxy</Note>
      </Version>
      <Version Name = ""2.1"">
        <Note>Football is awesome!</Note>
        <Note>Let's go sailing!</Note>
      </Version>
    </Report>");
    
    var lookup =
        doc
            .Descendants("Note")
            .ToLookup(
                x => x.Parent.Attribute("Name").Value,
                x => x.Value);
    

    这给了你这个查找:

    那么你可以这样做:

    var notes = lookup["2.1"].ToList();
    

    这给了你:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多