这是一个相当简单的解决方案
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ax21="my:ax21" exclude-result-prefixes="ax21"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vCols" select="/*/ax21:columnNames"/>
<xsl:variable name="vNumCols" select="count($vCols)"/>
<xsl:template match="ax21:result">
<result>
<xsl:apply-templates select=
"ax21:resultData[position() mod $vNumCols = 1]"
/>
</result>
</xsl:template>
<xsl:template match="ax21:resultData">
<item>
<xsl:apply-templates mode="create" select=
"(.|following-sibling::ax21:resultData)
[not(position() > $vNumCols) ]
"/>
</item>
</xsl:template>
<xsl:template match="ax21:resultData" mode="create">
<xsl:variable name="vPos" select="position()"/>
<xsl:element name="{$vCols[$vPos]}">
<xsl:value-of select="."/>
<xsl:if test="not(text())">
<xsl:value-of select=
"(.| preceding-sibling::ax21:resultData)
[position() mod $vNumCols = $vPos]
[text()]
[last()]
"/>
</xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
当此转换应用于以下XML文档时
<ax21:result type="test.ws.Result"
xmlns:ax21="my:ax21"
>
<ax21:columnNames>fileName</ax21:columnNames>
<ax21:columnNames>lockedState</ax21:columnNames>
<ax21:columnNames>currentLockOwner</ax21:columnNames>
<ax21:columnNames>UUID</ax21:columnNames>
<ax21:resultData>Test1.doc</ax21:resultData>
<ax21:resultData>true</ax21:resultData>
<ax21:resultData>analyst</ax21:resultData>
<ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData>
<ax21:resultData>Test2.doc</ax21:resultData>
<ax21:resultData>false</ax21:resultData>
<ax21:resultData/>
<ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData>
<ax21:resultData>Test3.doc</ax21:resultData>
<ax21:resultData>true</ax21:resultData>
<ax21:resultData>analyst</ax21:resultData>
<ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData>
<ax21:resultData>Test4.doc</ax21:resultData>
<ax21:resultData>false</ax21:resultData>
<ax21:resultData/>
<ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData>
</ax21:result>
产生了想要的结果
:
<result>
<item>
<fileName>Test1.doc</fileName>
<lockedState>true</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
<item>
<fileName>Test2.doc</fileName>
<lockedState>false</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
<item>
<fileName>Test3.doc</fileName>
<lockedState>true</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
<item>
<fileName>Test4.doc</fileName>
<lockedState>false</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
</result>
:
-
$vCols
和
$vNumCols
.
-
我们将模板应用于每个第N个
ax21:resultData
N mod $vNumCols = 1
. 每一个这样的元素都会开启一个新的世界
item
.
-
每一个
项目
由“无模式”下的模板匹配。这只是创建了包装
项目
元素,并应用于所有当前的$vnumcol
ax21:resultData
另一个模板中的元素
"create"
模式
-
“创建”
模式只创建一个元素,其名称是中第n个元素的值
哪里
n
position()
正在应用模板的当前()节点的。
-
最后,如果碰巧没有提供任何值,我们将(按倒序)获得同一类型元素的最新非空值。