在List <t>中选择许多XML节点

时间:2018-11-02 23:16:52

标签: c# xml linq

我需要一些帮助来选择所有<encoding>节点并将其添加到List<Core.Encoding>。我得到了高度和宽度的值,但是当我取消注释VideoCodec,AudioCodec和ContainerType时,出现错误

  

未设置为对象实例的对象引用。

有人有什么想法吗?

<media>
  <id>123456</id>
  <media_type>Video</media_type>
  <encodings>
    <encoding>
      <height>270</height>
      <width>404</width>
      <video_codec>H264</video_codec>
      <audio_codec>Aac</audio_codec>
      <container_type>Mp4</container_type>
    </encoding>
    <encoding>
      <height>270</height>
      <width>404</width>
      <video_codec>H264</video_codec>
      <audio_codec>Aac</audio_codec>
      <container_type>Mp4</container_type>
    </encoding>
  </encodings>
</media>

这是我到目前为止所拥有的:

[Serializable]
public class Encoding
{
    public string Height { get; set; }
    public string Width { get; set; }
    public string VideoCodec { get; set; }
    public string AudioCodec { get; set; }
    public string ContainerType { get; set; }
}

private List<Core.Encoding> SomeMethod(string authenticatedURL)
{
    XElement xml = XElement.Load(authenticatedURL);

    list.AddRange((from encoding in xml.DescendantsAndSelf("encoding")
                   select new Core.Encoding
                   {
                       Height = encoding.Element("height").Value,
                       Width = encoding.Element("width").Value,
                       VideoCodec = encoding.Element("video_codec").Value,
                       AudioCodec = encoding.Element("audio_codec").Value,
                       ContainerType = encoding.Element("container_type").Value
                   }));
}

2 个答案:

答案 0 :(得分:1)

我认为您的意思是,当您注释掉这些元素时会得到例外,因为它们不是文档的一部分。您只在不引发异常的状态下显示文档。

注释(退出),引发异常:

<!--<video_codec>H264</video_codec>-->

未注释,也不例外:

<video_codec>H264</video_codec>

您需要在所有这些null呼叫中检查Element。对?.属性进行null传播的访问(Value)是一种简单的方法:

VideoCodec = encoding.Element("video_codec")?.Value

答案 1 :(得分:0)

这有效(测试)(更新),我同时使用了c#5和c#7语法

using System;
using System.Xml.Linq;
using System.Xml;
using System.Linq;
// . . . . .  . .

// test data
var s = @"<media>
<id>123456</id>
<media_type>Video</media_type>
<encodings>
  <encoding>
    <height>270</height>
    <width>404</width>
    <video_codec>H264</video_codec>
    <audio_codec>Aac</audio_codec>
    <container_type>Mp4</container_type>
  </encoding>
  <encoding>
    <height>270</height>
    <width>404</width>
    <video_codec>H264</video_codec>
  <!--  <audio_codec>Aac</audio_codec> -->
    <container_type>Mp4</container_type>
  </encoding>
</encodings>
</media>";

var root = XElement.Parse(s);

// Linq to XML (select) 
var coll = root.Element("encodings").Elements("encoding").Select(e => new Encoding()
{
    Height = e.Element("height").Value,
    Width = e.Element("height").Value,
    // c#5
    VideoCodec = (e.Elements("video_codec").Any() ? e.Element("video_codec").Value : string.Empty),
    AudioCodec = (e.Elements("audio_codec").Any() ? e.Element("audio_codec").Value : string.Empty), 
    //  c#6
    ContainerType = e.Element("container_type")?.Value 
});

// test
coll.ToList().ForEach(e => Console.WriteLine(e.VideoCodec));

如果您有许多<media>标签,请使用SelectMany

coll.ToList()将列出您的名单