2015-09-12 182 views
1

我有一个看起来像下面的XML字符串:获取基于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"));

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

回答

2

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

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

通过改变你的建议,并通过大写我的V版本,它现在将正确数量的项目添加到列表中,但项目是空白的。 – tylerbhughes

+1

尝试使用node.InnerText代替oDnode.Value GetVersionNotes() – har07

1

你有另一种选择是使用LINQ到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); 

这就给了你这个查询:

lookup

然后,你可以这样做:

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

而且,让你:

result