输入文件:
<workorders>
<workorder>
<renew id="a">
<nodeA id="N1">
<fruit id="1" action="aaa">
<orange id="x" action="aa">
<attributes>
<color>Yellow</color>
<ada>xxx</ada>
</attributes>
</orange>
<orange id="y" action="change">
<attributes>
<color>Red</color>
<year>2012</year>
</attributes>
</orange>
<orange id="x" action="aa">
<attributes>
<color>Pink</color>
<ada>xxx</ada>
</attributes>
</orange>
<orange id="y" action="change">
<attributes>
<color>Blue</color>
<condition>good</condition>
</attributes>
</orange>
</fruit>
</nodeA>
</renew>
</workorder>
</workorders>
我的输出:
<workorders>
<workorder>
<renew id="a">
<nodeA id="N1">
<fruit id="1" action="aaa">
<orange id="x" action="aa">
<attributes>
<color>Pink</color>
<ada>xxx</ada>
</attributes>
</orange>
<orange id="y" action="change">
<attributes>
<color>Blue</color>
<year>2012</year>
<condition>good</condition>
</attributes>
</orange>
</fruit>
</nodeA>
</renew>
</workorder>
</workorders>
预期输出:
<workorders>
<workorder>
<renew id="a">
<nodeA id="N1">
<fruit id="1" action="aaa">
<orange id="x" action="aa">
<attributes>
<color>Yellow</color>
<ada>xxx</ada>
</attributes>
</orange>
<orange id="x" action="aa">
<attributes>
<color>Pink</color>
<ada>xxx</ada>
</attributes>
</orange>
<orange id="y" action="change">
<attributes>
<color>Blue</color>
<year>2012</year>
<condition>good</condition>
</attributes>
</orange>
</fruit>
</nodeA>
</renew>
</workorder>
</workorders>
XSL 文件:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:a="http://project.com">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="entity" match="/workorders/*/*/*/*/*" use="concat(parent::*/@id, '_', @id, '_', @action)"/>
<xsl:function name="a:is-primary" as="xs:boolean">
<xsl:param name="ctx"/>
<!-- need to establish "focus"(context) for the key() function to work -->
<xsl:for-each select="$ctx">
<xsl:sequence select="generate-id($ctx) = generate-id(key('entity', concat($ctx/parent::*/@id, '_', $ctx/@id, '_', $ctx/@action))[1])"/>
</xsl:for-each>
</xsl:function>
<xsl:function name="a:preceded-by" as="xs:boolean">
<xsl:param name="ctx"/>
<xsl:param name="action"/>
<xsl:value-of select="count($ctx/preceding::*[a:matches($ctx, ., $action)]) > 0"/>
</xsl:function>
<xsl:function name="a:followed-by" as="xs:boolean">
<xsl:param name="ctx"/>
<xsl:param name="action"/>
<xsl:value-of select="count($ctx/following::*[a:matches($ctx, ., $action)]) > 0"/>
</xsl:function>
<xsl:function name="a:matches" as="xs:boolean">
<xsl:param name="src"/>
<xsl:param name="target"/>
<xsl:param name="action"/>
<xsl:value-of select="
($src/local-name() = $target/local-name()) and
($src/parent::*/@id = $target/parent::*/@id) and
($src/@id = $target/@id) and
(if ($action = 'same')
then false()
else if ($action = 'any')
then ($target/@action = $src/@action)
else ($target/@action = $action))"/>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*/*/*/*/*[a:is-primary(.)]" priority="1">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="attributes" mode="consolidate-most-recent"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attributes" mode="consolidate-most-recent">
<xsl:copy>
<xsl:for-each-group
select="/workorders/*/*/*/*/*[a:matches(current()/parent::*, ., 'any')]/attributes/*"
group-by="local-name()">
<!-- take the last in the document order -->
<xsl:apply-templates select="current-group()[last()]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*/*/*/*/*[not(a:is-primary(.))]"/>
</xsl:stylesheet>
我应该在我的 xsl 文件中添加什么以使转换仅适用于具有组合的节点action="change"
?现在它将所有其他动作组合分组。
谢谢。