如何使用 xslt 根据复杂子元素属性的条件映射复杂元素列表

How to map a list of complex elements based on a condition on complex child element's attribute using xslt

我有一个 xml 文件,其结构如下,包含许多重复元素

已更新:在输入 xml 中,仅提供了那些可能导致映射发生变化的元素

    <offerList>
   <!--1 or more repetitions:-->
   <offer>
      <!--1 or more repetitions:-->
      <productList minQuantity="0" maxQuantity="1">
         <listType>1</listType>
         <!--1 or more repetitions:-->
         <productCategory minQuantity="0" maxQuantity="1">
            <controlType>11</controlType>
            <product minQuantity="0" maxQuantity="1">
               <productKey>111</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="false" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1111</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1112</optionKeyType>
               </productOption>
            </product>
            <product minQuantity="0" maxQuantity="1">
               <productKey>112</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1121</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="false" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1122</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="true" picked="false" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1123</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="false" picked="false" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1124</optionKeyType>
               </productOption>
            </product>
         </productCategory>
         <productCategory minQuantity="0" maxQuantity="1">
            <controlType>12</controlType>
            <!--1 or more repetitions:-->
            <product minQuantity="0" maxQuantity="1">
               <productKey>121</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="false" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1211</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="false" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1212</optionKeyType>
               </productOption>
            </product>
         </productCategory>
         <productCategory minQuantity="0" maxQuantity="1">
            <controlType>13</controlType>
            <!--1 or more repetitions:-->
            <product minQuantity="0" maxQuantity="1">
               <productKey>131</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1311</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="false" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1312</optionKeyType>
               </productOption>
            </product>
         </productCategory>
      </productList>
   </offer>
</offerList>

我想提取属性为

的所有 productCategory 元素
productOption

使用 Xpath

offerList/offer/productList/productCategory/product/productOption

条件是

either rulePicked is true or picked is false

我尝试创建的 XSLT 是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
          <xsl:variable name="ListOfCategory">
             <xsl:for-each select="offerList/offer">
                <xsl:for-each select="./productList">
                   <xsl:for-each select="./productCategory">
                      <xsl:for-each select="./product">
                         <xsl:for-each select="./productOption">
                            <xsl:if test="(./@rulePicked = true) or (./@picked = false)">
                               <xsl:copy-of select="../../../"/>
                            </xsl:if>
                         </xsl:for-each>
                      </xsl:for-each>
                   </xsl:for-each>
                </xsl:for-each>
             </xsl:for-each>
          </xsl:variable>
    </xsl:template>
 </xsl:stylesheet>

此 XSLT 正在为满足条件的每个 productOption 创建一个 productCategory 元素。

但我想要 productCategory 元素,其中包含所有满足条件的 productOptions。以及该 ProductCategory 中的所有其他 productOprions 都必须删除。

对于我给出的输入,我想要的输出应该是这样的:

<offerList>
   <!--1 or more repetitions:-->
   <offer>
      <!--1 or more repetitions:-->
      <productList minQuantity="0" maxQuantity="1">
         <listType>1</listType>
         <!--1 or more repetitions:-->
         <productCategory minQuantity="0" maxQuantity="1">
            <controlType>11</controlType>
            <product minQuantity="0" maxQuantity="1">
               <productKey>111</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1112</optionKeyType>
               </productOption>
            </product>
            <product minQuantity="0" maxQuantity="1">
               <productKey>112</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1121</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="true" picked="false" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1123</optionKeyType>
               </productOption>
               <productOption disable="?" rulePicked="false" picked="false" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1124</optionKeyType>
               </productOption>
            </product>
         </productCategory>
         <productCategory minQuantity="0" maxQuantity="1">
            <controlType>13</controlType>
            <!--1 or more repetitions:-->
            <product minQuantity="0" maxQuantity="1">
               <productKey>131</productKey>
               <!--1 or more repetitions:-->
               <productOption disable="?" rulePicked="true" picked="true" defaultSelection="?" requireValidation="?">
                  <optionKeyType>1311</optionKeyType>
               </productOption>
            </product>
         </productCategory>
      </productList>
   </offer>
</offerList>

谁能帮我搞定这个。

提前致谢

编辑以回应澄清:

这样试试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="offer[not(productList/productCategory/product/productOption[@rulePicked='true' or @picked='false'])]"/>
<xsl:template match="productList[not(productCategory/product/productOption[@rulePicked='true' or @picked='false'])]"/>
<xsl:template match="productCategory[not(product/productOption[@rulePicked='true' or @picked='false'])]"/>
<xsl:template match="product[not(productOption[@rulePicked='true' or @picked='false'])]"/>
<xsl:template match="productOption[not(@rulePicked='true' or @picked='false')]"/>

</xsl:stylesheet>

这会复制您输入的所有内容原样,除了:

  • 任何不满足条件的productOption

  • 任意product没有至少一个productOptionchild满足条件;

  • 任何 productCategory 没有至少一个 productOption 满足条件的后代;

  • 任何 productList 没有至少一个 productOption 满足条件的后代;

  • 任何 offer 没有至少一个 productOption 满足条件的后代。