如何使用 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
没有至少一个productOption
child满足条件;
任何 productCategory
没有至少一个 productOption
满足条件的后代;
任何 productList
没有至少一个 productOption
满足条件的后代;
任何 offer
没有至少一个 productOption
满足条件的后代。
我有一个 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
没有至少一个productOption
child满足条件;任何
productCategory
没有至少一个productOption
满足条件的后代;任何
productList
没有至少一个productOption
满足条件的后代;任何
offer
没有至少一个productOption
满足条件的后代。