C# 读取 XML 层次结构并使用父级的故障转移

本文关键字:故障 转移 读取 XML 层次结构 | 更新日期: 2023-09-27 18:30:56

我想创建以下XML。
一个父级中的许多孩子,父级包含与孩子相关的节点(作为孩子的默认值),如果孩子缺少节点,父节点将是故障转移并为 KIS 提供其默认节点。

<parents>
   <parent>
      <!--all parent related nodes will be here-->
      <kid-prop>default kid prop</kid-prop><!--this is the default for all kids-->
      <kids>
         <kid>
            <kid-prop>some data</kid-prop>
         </kid>
         <kid></kid><!--since this kid does not have have <kid-prop>, it will be taken from the parent-->
      <kids>
   <parent>
<parents>

如何以编程方式做到这一点是不费吹灰之力的,问题是,是否有任何注释方法可以告诉 xmlreader 父母是孩子的故障转移,以防孩子丢失某些东西

C# 读取 XML 层次结构并使用父级的故障转移

否 - XmlReader 将按原样读取 XML,没有"注释"的概念。 如果你使用的是System.Xml.Linq而不是XmlReader,那就很容易了:

var defaultValue = (string)root.Element("parent").Element("kid-prop");
root.Element("parent").Element("kids")
.Elements("kid")
.Select(kid => 
       kid.Elements("kid-prop").Any() ? 
       (string)kid.Element("kid-prop") : defaultValue);

通过使用 XmlReader,您可以解决需求,但它需要大量检查

下面是示例代码

     using (XmlReader reader = XmlReader.Create(@"D:'Sample.xml"))
        {
            bool b = false;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "parent")
                    {
                        b = true;
                    }
                    if (reader.Name == "kid")
                        b = false;
                    if (!b && reader.Name == "kid-prop")
                    {
                        Console.WriteLine(reader.ReadElementContentAsString());
                    }
                    if (b && reader.Name == "kid-prop")
                    {
                        Console.WriteLine(reader.ReadElementContentAsString());
                    }
                }
            }
        }

否则,最好使用 linq to xml,如下所示

        XElement root = XElement.Load(@"D:'Sample.xml");
        var coll = root.Element("parent").Element("kids").Elements("kid").Select(kid => kid.Elements("kid-prop").Any() ? (string)kid.Element("kid-prop") : (string)root.Element("parent").Element("kid-prop"));
        foreach (var item in coll)
        {
            Console.WriteLine(item);
        }