根据另一个标记值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查找重复元素

使用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_typePrimary的子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();