使用 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 个约束
- "variable" 或元素在
<VariableBlockBase>
中不重复
- 一个"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;
}
}
}
嗨,我收到了下面的 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 个约束
- "variable" 或元素在
<VariableBlockBase>
中不重复
- 一个"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;
}
}
}