根据另一个标记值XML查找重复元素
本文关键字:查找 元素 XML 另一个 | 更新日期: 2023-09-27 18:09:15
我有一个非常复杂的XML,我需要检查一个特定元素是否在XML的每个子元素中只存在一次。
<?xml version="1.0" encoding="UTF-8"?>
<deal>
<commercial>
<party />
<party>
<role_detail>
<role_type>Primary</role_type>
</role_detail>
<listingagents>
<listingagent>1</listingagent>
<listingagent>2</listingagent>
</listingagents>
</party>
<party>
<role_detail>
<role_type>Secondary</role_type>
</role_detail>
<listingagents>
<listingagent>1</listingagent>
</listingagents>
</party>
<party />
</commercial>
<commercial />
<commercial />
</deal>
当party标记具有role_type = PRIMARY时,每个商业标记应仅包含一个listingagent标记。
对于每个商业广告,我需要挑选类型为Primary的一方,然后检查listingagents标记,它应该只包含一个子listingagent。
使用XML Schema。XSD和限制您的发生:
例如:<xs:element name="listingagents" maxOccurs="unbounded" type="listingagentsType"/>
<xs:complexType name="listingagentsType">
<xs:sequence>
<xs:element name="listingagent" type="parameterType" maxOccurs="1"/>
</xs:sequence>
XElement xml = //...
bool xmlIsInvalid = xml.Elements("commercial")
.Select(c => c.Elements("party")
.Single(p => p.Element("role_detail").Element("role_type").Value == "Primary"))
.Any(p => p.Element("listingagents").Elements("listingagent").Count() > 1);
对于每一个commercial
元素,得到role_type
为Primary
的子party
元素。如果这些party
元素中的任何一个在listingagents
中包含超过1个listingagent
,则返回true。
注意这个解决方案假设了一些关于XML结构的事情-即party
将始终有一个子role_detail
元素,listingagents
将始终至少有一个listingagent
,等等。
我喜欢用XDocument (System.Xml.Linq)查询XML节点。我会首先找到拥有1个以上上市代理的无效主要方,然后从那里开始……
XDocument doc = XDocument.Parse(File.ReadAllText("XMLFile1.xml"));
var allParties = doc.Descendants("commercial").Elements("party");
// invalid primary parties with more than 1 listing agent
var invalidPrimaries = allParties.Where(p => p.Element("role_detail")?.Value.ToUpper() == "PRIMARY" &&
p.Element("listingagents")?.Elements("listingagent").Count() > 1);
var validParties = allParties.Except(invalidPrimaries);
var validCommericals = validParties.Select(p => p.Parent).Distinct().ToList();