【问题标题】:Selecting XmlNode's Child Nodes based on Tag基于 Tag 选择 XmlNode 的子节点
【发布时间】:2018-10-13 08:41:22
【问题描述】:

我正在尝试解析这个 XML 文档:

<MPD>
  <Period duration="PT0H3M1.63S" start="PT0S">
    <AdaptationSet>
      <ContentComponent contentType="video" id="1" />
      <Representation bandwidth="4190760" codecs="avc1.640028" height="1080" id="1" mimeType="video/mp4" width="1920">
        <BaseURL>car-20120827-89.mp4</BaseURL>
      </Representation>
      <Representation bandwidth="2073921" codecs="avc1.4d401f" height="720" id="2" mimeType="video/mp4" width="1280">
        <BaseURL>car-20120827-88.mp4</BaseURL>
      </Representation>
    </AdaptationSet>
    <AdaptationSet>
      <ContentComponent contentType="audio" id="2" />
      <Representation bandwidth="127236" codecs="mp4a.40.2" id="6" mimeType="audio/mp4" numChannels="2" sampleRate="44100">
        <BaseURL>car-20120827-8c.mp4</BaseURL>
      </Representation>
      <Representation bandwidth="255236" codecs="mp4a.40.2" id="7" mimeType="audio/mp4" numChannels="2" sampleRate="44100">
        <BaseURL>car-20120827-8d.mp4</BaseURL>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

使用此 C# 代码:

var rootDoc = new XmlDocument();
rootDoc.LoadXml(xmlString); // the one from above

var adaptationSets = rootDoc.GetElementsByTagName("AdaptationSet");

if (adaptationSets.Count > 0)
    foreach (XmlNode adaptionSet in adaptationSets) // Loop through AdaptionSets
    {
        // Get the one Node in this AdaptionSet with the ContentComponent-Tag
        var contentComponent = adaptionSet.SelectSingleNode("ContentComponent");

        if (contentComponent != null)
        {
            // parse attributes
        }

        // Get All Nodes in this AdaptionSet with the Representation-Tag
        var representations = adaptionSet.SelectNodes("Representation");

        if(representations?.Count > 0)
            foreach (XmlNode representation in representations)
            {
                // parse attributes of XmlNode
            }
    }

除了 XPath 查询之外,它都可以工作。我尝试了很多带有前导“/”、“//”、“./”且没有任何前导字符的变体,但它就是行不通。我究竟做错了什么?我没有定期使用 XPath,除了我提到的主要字符外,我找不到任何东西。因为我在这个网站上的很多其他答案中都看到了它,所以我觉得我应该提一下,我正在明确寻找可以帮助我解决这个问题的 XPath,而不是一些 Linq 变体或完全不同的方法。

非常感谢任何帮助。提前致谢!

【问题讨论】:

    标签: c# xml xpath


    【解决方案1】:

    我认为这可以解决您的问题:

    var rootDoc = new XmlDocument();
    rootDoc.LoadXml(xmlString); // the one from above
    
    var adaptationSets = rootDoc.SelectNodes("//AdaptationSet");
    
    if (adaptationSets.Count > 0)
        foreach (XmlNode adaptionSet in adaptationSets) // Loop through AdaptionSets
        {
            // Get the one Node in this AdaptionSet with the ContentComponent-Tag
            var contentComponent = adaptionSet.SelectSingleNode("./ContentComponent");
    
            if (contentComponent != null)
            {
                // parse attributes
            }
    
            // Get All Nodes in this AdaptionSet with the Representation-Tag
            var representations = adaptionSet.SelectNodes("./Representation");
    
            if (representations?.Count > 0)
                foreach (XmlNode representation in representations)
                {
                    // parse attributes of XmlNode
                }
        }
    

    【讨论】:

      【解决方案2】:

      尝试使用 xml linq :

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Linq;
      
      namespace ConsoleApplication1
      {
          class Program
          {
              const string FILENAME = @"c:\temp\test.xml";
              static void Main(string[] args)
              {
                  XDocument doc = XDocument.Load(FILENAME);
                  XElement period = doc.Descendants("Period").FirstOrDefault();
      
                  MPD mpd = new MPD();
                  mpd.duration = (string)period.Attribute("duration");
                  mpd.start = (string)period.Attribute("start");
                  mpd.adaptions = period.Elements("AdaptationSet").Select(x => new Adaption() {
                      contentType = (string)x.Element("ContentComponent").Attribute("contentType"),
                      id = (int)x.Element("ContentComponent").Attribute("id"),
                      representations = x.Elements("Representation").Select(y => new Representation() {
                          bandwidth = (int)y.Attribute("bandwidth"),
                          codecs = (string)y.Attribute("codecs"),
                          height = (int?)y.Attribute("height"),
                          id = (int)y.Attribute("id"),
                          mimeType = (string)y.Attribute("mimeType"),
                          width = (int?)y.Attribute("width"),
                          baseURL = (string)y.Descendants("BaseURL").FirstOrDefault()
                      }).ToList()
                  }).ToList();
      
              }
          }
          public class MPD
          {
              public string duration { get; set; }
              public string start { get; set; }
              public List<Adaption> adaptions { get; set; }
          }
          public class Adaption
          {
              public string contentType { get; set; }
              public int id { get; set; }
              public List<Representation> representations { get; set; }
          }
          public class Representation
          {
              public int bandwidth { get; set; }
              public string codecs { get; set; }
              public int? height { get; set; }
              public int id { get; set; }
              public string mimeType { get; set; }
              public int? width { get; set; }
              public string baseURL { get; set; }
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2012-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多