【问题标题】:Find duplicate tags in xml with c#用c#在xml中查找重复的标签
【发布时间】:2018-03-16 20:29:13
【问题描述】:

嗨,我得到了下面的 xml

<InstanceData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <letter>
        <variableBlocks>
            <VariableBlockBase xsi:type="ClientVariableBlock">
                <FirstName></FirstName>
                <LastName></LastName>
                <Address></Address>
            </VariableBlockBase>
            <VariableBlockBase xsi:type="PaymentVariableBlock">
                <LastPaymentDate></LastPaymentDate>
                <LastPaymentAmount></LastPaymentAmount>
                <Address></Address> <!-- repeated (Address appear in the VariableBlockBase above) so this xml should be invalid -->
            </VariableBlockBase>
      </variableBlocks>
    </letter>
</InstanceData>

该 xml 正在动态地构建。 每个&lt;VariableBlockBase&gt; 都有一组或变量(名字、地址等) 我要检查 2 个约束

  1. “变量”或元素在&lt;VariableBlockBase&gt; 中不重复
  2. “变量”或元素仅出现在一个&lt;VariableBlockBase&gt;

在示例 xml 中,&lt;Address&gt; 出现在两个 &lt;VariableBlockBase&gt; 实例(客户端和付款)中

我想创建一个 Linq 查询来获取重复标签的列表。我在 XmlDocument 实例中得到了这个 xml。

【问题讨论】:

  • 您的意思是“在VariableBlockBase 元素内”吗?是 all VariableBlockBase 元素,还是只是在同一个 letter 元素中的那些?您需要非常非常明确地提出您的要求。
  • 每个变量块都有一组变量,变量不能在多个变量块中,也不能在自己的块中。在示例 xml 中,地址重复。我想检测一下。
  • 请编辑您的问题以澄清这一点 - 请注意当前您的 XML 有 variableBlocks,而不是 variableBlock
  • 构建 xsd 架构并使用 schems 验证 xml:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…

标签: c# xml linq-to-xml


【解决方案1】:

我不确定将所有代码放在一个 linq 查询中,但这里是非 linq 解决方案:

string xml = @"<InstanceData xmlns:xsi=""http://www.w3.org/2001/XMLSchema-
instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                            <letter>
                            <variableBlocks>
                                <VariableBlockBase xsi:type=""ClientVariableBlock"">
                                    <FirstName></FirstName>
                                    <LastName></LastName>
                                    <Address></Address>
                                </VariableBlockBase>
                                <VariableBlockBase xsi:type=""PaymentVariableBlock"">
                                    <LastPaymentDate></LastPaymentDate>
                                    <LastPaymentAmount></LastPaymentAmount>
                                    <Address></Address> <!-- repeated (Address appear in the VariableBlockBase above) so this xml should be invalid -->
                                </VariableBlockBase>
                          </variableBlocks>
                        </letter>
                    </InstanceData>";
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);
        XmlNodeList allElements = doc.SelectNodes("//VariableBlockBase/*");
        foreach(XmlElement childNode in doc.SelectNodes("InstanceData/letter/variableBlocks/*"))
        {
            foreach ( XmlElement grandChildNode in childNode.ChildNodes )
            {
                try
                {
                    allElements.Cast<XmlElement>().SingleOrDefault(x => x.Name == grandChildNode.Name);
                }
                catch ( InvalidOperationException )
                {
                    throw new Exception("The tag <" + grandChildNode.Name + "> has been found more than once");
                }
                catch
                {
                    throw;
                }
            }
        }

【讨论】:

  • 谢谢,这正是我想要的。
  • 顺便说一句,“非 linq 解决方案”是错误的,因为它使用了 LINQ。
猜你喜欢
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多