使用 C# 在 xml 中查找重复标签

Find duplicate tags in xml with c#

嗨,我收到了下面的 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 正在动态构建。 每个 <VariableBlockBase> 都有一个集合或变量(名字、地址等) 我想检查 2 个约束

  1. "variable" 或元素在 <VariableBlockBase>
  2. 中不重复
  3. 一个"variable"或元素只出现在一个<VariableBlockBase>

在示例 xml 中看到 <Address> 出现在两个 <VariableBlockBase> 实例中(客户端和付款)

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

我不确定是否将所有代码放在一个 linq 查询中,但这是 non-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;
                }
            }
        }