使用XSLT 2(saxon8)将元素从一个地方移动到另一个地方
大家好,请帮我用XSLT 2.0生成以下输出。
我有这个:
<UL>
<ITEM>
aaa
<NL>iii
<ITEM1>111</ITEM1>
<ITEM2>222</ITEM2>
</NL>
</ITEM>
<ITEM>
bbb
<NL>vvv
<ITEM1>333</ITEM1>
<ITEM2>444</ITEM2>
</NL>
</ITEM>
</UL>
我需要制作这个
<UL>
<ITEM>
aaa
<ITEM1>111</ITEM1>
</ITEM>
<ITEM>
bbb
<ITEM1>333</ITEM1>
</ITEM>
<NEW>
<NL>iii
<ITEM2>222</ITEM2>
</NL>
<NL>vvv
<ITEM2>444</ITEM2>
</NL>
</NEW>
</UL>
我正在尝试使用模式选项获取输出,如下所述:
<xsl:stylesheet version="2.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="NL"/>
<xsl:template match="ITEM2"/>
<xsl:template match="UL">
<xsl:copy>
<xsl:apply-templates/>
<NEW>
<xsl:apply-templates select="descendant::NL" mode="move"/>
</NEW>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM" mode="move">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="descendant::ITEM2" mode="move1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NL" mode="move">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM2" mode="move1">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
谢谢和问候
巴拉
答案 0 :(得分:0)
这是一个XSLT 2.0样式表,它可以创建你想要的结构,虽然空白区域不同,因为混合内容产生精确输出是一个问题:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="UL">
<xsl:copy>
<xsl:for-each-group select="ITEM" group-by="NL/*/node-name(.)">
<xsl:choose>
<xsl:when test="position() eq 1">
<xsl:for-each select="current-group()">
<ITEM>
<xsl:apply-templates select="text() | NL/*[node-name(.) eq current-grouping-key()]"/>
</ITEM>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<NEW>
<xsl:for-each select="current-group()">
<NL>
<xsl:apply-templates select="NL/(text() | *[node-name(.) eq current-grouping-key()])"/>
</NL>
</xsl:for-each>
</NEW>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="NL/*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我得到了结果
<UL><ITEM>
aaa
<ITEM1>111</ITEM1>
</ITEM><ITEM>
bbb
<ITEM1>333</ITEM1>
</ITEM><NEW><NL>iii
<ITEM2>222</ITEM2>
</NL><NL>vvv
<ITEM2>444</ITEM2>
</NL></NEW></UL>
当我添加指令以从输入中去除空白区域并缩进输出时,如
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="UL">
<xsl:copy>
<xsl:for-each-group select="ITEM" group-by="NL/*/node-name(.)">
<xsl:choose>
<xsl:when test="position() eq 1">
<xsl:for-each select="current-group()">
<ITEM>
<xsl:apply-templates select="text() | NL/*[node-name(.) eq current-grouping-key()]"/>
</ITEM>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<NEW>
<xsl:for-each select="current-group()">
<NL>
<xsl:apply-templates select="NL/(text() | *[node-name(.) eq current-grouping-key()])"/>
</NL>
</xsl:for-each>
</NEW>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="NL/*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果是
<UL>
<ITEM>
aaa
<ITEM1>111</ITEM1>
</ITEM>
<ITEM>
bbb
<ITEM1>333</ITEM1>
</ITEM>
<NEW>
<NL>iii
<ITEM2>222</ITEM2>
</NL>
<NL>vvv
<ITEM2>444</ITEM2>
</NL>
</NEW>
</UL>
作为替代方案,如果我们知道我们想要拆分ITEM1
和ITEM2
,那么这里是使用模式的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NL">
<xsl:apply-templates select="ITEM1"/>
</xsl:template>
<xsl:template match="ITEM2"/>
<xsl:template match="UL">
<xsl:copy>
<xsl:apply-templates/>
<NEW>
<xsl:apply-templates select="descendant::NL" mode="move"/>
</NEW>
</xsl:copy>
</xsl:template>
<xsl:template match="ITEM1" mode="move"/>
</xsl:stylesheet>