我不确定标题是否清楚地解释了我的问题,我会尽量包含尽可能多的细节。
我需要使用Xslt 1将xml转换为格式正确的格式,以便我可以将其反序列化为.net类型。
源XML
<ax21:result type="test.ws.Result">
<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>
目标XML
<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>true</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
<item>
<fileName>Test2.doc</fileName>
<lockedState>true</lockedState>
<currentLockOwner>analyst</currentLockOwner>
<UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID>
</item>
</result>
可以使用xslt完成吗?如果是,请发布链接或示例xslt供我试用。
我正在使用.net 2.0,c#,XSLT 1.0
答案 0 :(得分:3)
这是一个相当简短的解决方案:
<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
中。
我们正在将模板应用于每个第ax21:resultData
个元素,其中N mod $vNumCols = 1
。每个这样的元素都会启动一个新的item
。
ax21:resultData
中第一个item
元素与“无模式”中的模板匹配。这只是创建包装item
元素,并以ax21:resultData
模式应用于所有当前的$ vNumCols "create"
元素另一个模板。
"create"
模式下的模板只创建一个元素,其名称是$vCols
中第n个元素的值,其中n
是position()
正在应用模板的current()节点。
最后,如果没有提供任何值,我们会(按向后的顺序)获得相同类型元素的最新非空值。
答案 1 :(得分:0)
如果不是不可能的话,那将是非常艰难的,以便正确可靠地完成。
问题是:在许多人和节点上没有关于他们的类型/位置的索引或类型的指示 - 你必须或多或少地猜测......
如果至少有一个额外的属性,例如等等,这将是一个不同的故事 - 这样一来,人们可能会以某种方式将这些属性联系在一起。
有没有机会你可以“按摩”原始数据?否则,我可能会说你必须在C#中加载它并解析它并进行大量的手动处理以获得你想要的东西。
马克