如何在XML标签内获取价值?

时间:2015-12-29 10:57:11

标签: c# xml xml-parsing

我有以下XML结构:

<Document>
  <Sectors>
    <Sector>
      SectorName1
      <Subsectors>
        <Subsector>Subsector1</Subsector> 
        <Subsector>Subsector2</Subsector> 
      </Subsectors>
    </Sector>
    <Sector>
      SectorName2
      <Subsectors>
        <Subsector>Subsector1</Subsector> 
        <Subsector>Subsector2</Subsector> 
      </Subsectors>
    </Sector>
  </Sectors>  
</Document>

我也有反序列化的课程:

    public class MetaDataXML
    {
        public class SectorXML
        {
            [XmlArrayItem(ElementName = "Sector")]
            string SectorName { get; set; }

            [XmlArray]
            [XmlArrayItem(ElementName = "Subsector")]
            public List<string> Subsectors { get; set; }
        }

        public List<SectorXML> Sectors { get; set; }
    }

进行反序列化的部分代码:

var xRoot = new XmlRootAttribute { ElementName = "Document", IsNullable = true };
var reader = new XmlSerializer(typeof(MetaDataXML), xRoot);
var data = (MetaDataXML)reader.Deserialize(streamXML);

反序列化后,我成功获得了子部分的velues,但我没有得到SectorName的值。我需要如何组织我的类结构,我将为我的字符串SectorName属性获取值“SectorName1”和“SectorName2”?

我发现这种情况是“混合内容”。我们如何解析这些文本值?

1 个答案:

答案 0 :(得分:1)

虽然我不完全确定你要在这里实现什么,但我已经对你的XML类进行了一些修改,并提供了一些示例代码,它能够检索有关扇区的所有信息,包括其名称和其中所有子部门的名称。

XML类:

namespace DocumentXml
{
    [XmlRoot("Document")]
    public class Document
    {
        [XmlArray("Sectors")]
        [XmlArrayItem("Sector")]
        public Sector[] Sectors { get; set; }
    }

    [XmlRoot("Sector")]
    public class Sector
    {
        [XmlAttribute("SectorName")]
        public string SectorName { get; set; }
        [XmlArray("Subsectors")]
        [XmlArrayItem("Subsector")]
        public string[] Subsectors { get; set; }
    }
}

主程序类:

namespace DocumentXml
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = @"D:\sandbox\DocumentXml\DocumentXml\Sample.xml";
            var serializer = new XmlSerializer(typeof(Document));
            var document = serializer.Deserialize(File.OpenRead(path)) as Document;
            var sectors = document.Sectors;
            foreach (var s in sectors)
            {
                Console.WriteLine($"Sector Name: {s.SectorName}");
                foreach (var ss in s.Subsectors)
                {
                    Console.WriteLine($"Subsector Name: {ss}");
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }
}

示例XML:

<Document>
  <Sectors>
    <Sector SectorName="SectorName1">
      <Subsectors>
        <Subsector>Subsector1</Subsector>
        <Subsector>Subsector2</Subsector>
      </Subsectors>
    </Sector>
    <Sector SectorName="SectorName2">
      <Subsectors>
        <Subsector>Subsector1</Subsector>
        <Subsector>Subsector2</Subsector>
      </Subsectors>
    </Sector>
   </Sectors>
</Document>

输出:

Console Output

修改

由于无法更改XML结构,因此这个新类将保留结构,并允许您获取有问题的值。 XmlText返回值内的所有内容,因此必须使用自定义集来确保从中正确地修剪空白。

[XmlRoot("Document")]
public class MetaDataXml
{
    [XmlArray("Sectors")]
    [XmlArrayItem("Sector")]
    public Sector[] Sectors { get; set; }
}

[XmlRoot("Sector")]
public class Sector
{
    [XmlIgnore]
    private string _sectorName;

    [XmlText]
    public string SectorName
    {
        get
        {
            return _sectorName;
        }
        set
        {
            _sectorName = value.Trim();
        }
    }

    [XmlArray]
    [XmlArrayItem(ElementName = "Subsector")]
    public List<string> Subsectors { get; set; }
}

示例程序:

class Program
{
    static void Main(string[] args)
    {
        var path = @"D:\sandbox\DocumentXml\DocumentXml\Sample.xml";

        using (var stream = File.OpenRead(path))
        {
            var deserializer = new XmlSerializer(typeof(MetaDataXml));
            var data = (MetaDataXml)deserializer.Deserialize(stream);
            foreach (var s in data.Sectors)
            {
                Console.WriteLine($"Sector Name: {s.SectorName}");
                foreach (var ss in s.Subsectors)
                {
                    Console.WriteLine($"Subsector Name: {ss}");
                }
                Console.WriteLine();
            }
        }
        Console.ReadKey();
    }
}