我需要分析以下XML输入:
:optional => true
并使用Xslt对其进行转换以获得以下结果:
<LIST>
<PRODUCT TYPE="1" REP="0">
<SUB CAT="1.1" COUNT="2">
<ITEM NAME="OCC" BEGIN="0" ND="49">
</ITEM>
<ITEM NAME="OCC" BEGIN="0" END="49">
</ITEM>
</SUB>
</PRODUCT>
<PRODUCT TYPE="1" REP="1">
<SUB CAT="1.1" COUNT="1">
<ITEM NAME="PRC" BEGIN="0" END="49">
</ITEM>
</SUB>
</PRODUCT>
</LIST>
我需要做的是检查两个不同PRODUCT节点中的ITEMS的BEGIN和END是否相同,如果是这种情况,请将MULTIPLE节点添加为标志。 有关如何进行的任何想法? 这就是我认为它可以工作的方式:
<LIST>
<PRODUCT TYPE="1" REP="0">
<SUB CAT="1.1" COUNT="2">
<MULTIPLE />
<ITEM NAME="OCC" BEGIN="0" END="49">
</ITEM>
<MULTIPLE />
<ITEM NAME="OCC" BEGIN="0" END="49">
</ITEM>
</SUB>
</PRODUCT>
<PRODUCT TYPE="1" REP="1">
<SUB CAT="1.1" COUNT="1">
<MULTIPLE />
<ITEM NAME="PRC" BEGIN="0" END="49">
</ITEM>
</SUB>
</PRODUCT>
</LIST>
&#13;
答案 0 :(得分:1)
这可以通过查找ITEM
元素
<xsl:key name="item" match="ITEM" use="concat(@BEGIN, '|', @END)" />
然后,您只需要一个匹配ITEM
元素的模板,其中密钥中至少有2个项目
<xsl:template match="ITEM[key('item', concat(@BEGIN, '|', @END))[2]]">
将此与XSLT标识转换结合使用,为您提供此XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="item" match="ITEM" use="concat(@BEGIN, '|', @END)" />
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM[key('item', concat(@BEGIN, '|', @END))[2]]">
<MULTIPLE />
<xsl:call-template name="identity" />
</xsl:template>
</xsl:stylesheet>
如果您希望将其限制为在同一产品和子类别中查找匹配项,请将密钥更改为此...
<xsl:key name="item" match="ITEM" use="concat(../../@TYPE, '|', ../@CAT, '|', @BEGIN, '|', @END)" />
并相应调整模板匹配....
<xsl:template match="ITEM[key('item', concat(../../@TYPE, '|', ../@CAT, '|', @BEGIN, '|', @END))[2]]">
答案 1 :(得分:1)
您可以通过匹配ITEM上下文来尝试这种方式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM">
<xsl:if test="(
(@BEGIN = ancestor::PRODUCT/following-sibling::PRODUCT/descendant::ITEM/@BEGIN) and
(@END = ancestor::PRODUCT/following-sibling::PRODUCT/descendant::ITEM/@END))
or (
(@BEGIN = ancestor::PRODUCT/preceding-sibling::PRODUCT/descendant::ITEM/@BEGIN) and
(@END = ancestor::PRODUCT/preceding-sibling::PRODUCT/descendant::ITEM/@END)
)
">
<xsl:element name="MULTIPLE"/>
</xsl:if>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>