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

时间:2015-11-24 11:21:14

标签: xml xslt attributes parent-child

我有一个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>

任何人都可以帮我解决这个问题。

提前致谢

1 个答案:

答案 0 :(得分:0)

编辑以回应澄清:

以这种方式尝试:

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没有满足条件的至少一个productOption孩子;

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

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

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