我有以下xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<cases>
<case>
<key>123</key>
</case>
<case>
<key>456</key>
</case>
</cases>
<issues>
<issue>
<issueid>issue1</issueid>
<casekey>123</casekey>
</issue>
<issue>
<issueid>issue2</issueid>
<casekey>123</casekey>
</issue>
<issue>
<issueid>issue3</issueid>
<casekey>456</casekey>
</issue>
</issues>
</root>
我想将所有<issue>
个节点移至<case>
,其<casekey>
值等于<key>
的{{1}}值。
换句话说,如果<case>
的{{1}}值等于<casekey>
的{{1}}值,则将<issue>
移到<key>
下<case>
。
我的最终xml应如下所示:
issue
答案 0 :(得分:1)
主要是匹配案例的模板,包括:
最后要添加的是阻止问题标记的“正常”处理。
下面是一个有效的解决方案:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="case">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:variable name="kk" select="key"/>
<xsl:apply-templates select="../../issues/issue[casekey=$kk]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="issues"/>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
答案 1 :(得分:1)
XSLT有一个内置的 key 机制来解决交叉引用 - 最好使用它:
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="*"/>
<xsl:key name="issues" match="issue" use="casekey" />
<xsl:template match="/root">
<root>
<cases>
<xsl:for-each select="cases/case">
<case>
<xsl:copy-of select="key"/>
<xsl:copy-of select="key('issues', key)"/>
</case>
</xsl:for-each>
</cases>
</root>
</xsl:template>
</xsl:stylesheet>
P.S。不要将对XML中的key
元素的引用与xsl:key
指令和key()
函数混淆。
答案 2 :(得分:1)
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<root>
<xsl:apply-templates select="cases"/>
</root>
</xsl:template>
<xsl:template match="case">
<xsl:variable name="keyvalue" select="normalize-space(key/text())"/>
<case>
<xsl:copy-of select="key"/>
<xsl:if test="ancestor::cases/following-sibling::issues/descendant::casekey = $keyvalue">
<xsl:copy-of
select="ancestor::cases/following-sibling::issues/issue[casekey = $keyvalue]"/>
</xsl:if>
</case>
</xsl:template>
<xsl:template match="issue[child::casekey = preceding::key]"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>