在下面的xslt转换中是输入xml。
<root xmlns="test1">
<Entries xmlns="test2">
<root xmlns="test1">
<LAT>1</LAT>
</root>
<root xmlns="test1">
<LAT>2</LAT>
</root>
</Entries>
<Entries xmlns="test2">
<root xmlns="test1">
<LAT>3</LAT>
</root>
<root xmlns="test1">
<LAT>4</LAT>
</root>
</Entries>
</root>
我针对此xml使用的XSLT代码是。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:p="test1"
xmlns:r="test2"
version="1.0">
<xsl:template match="//*[local-name()='root']">
<xsl:element name="Test">
<xsl:for-each select="//p:root/r:Entries">
<xsl:variable name="i" select="position()"/>
<xsl:for-each select="//p:root/r:Entries/p:root">
<xsl:element name="{concat('imei', $i)}"> <xsl:element name="LAT"><xsl:value-of select="//*[local-name()='LAT']"/></xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我想要的结果是:
<Test>
<imei1>
<LAT>1</LAT>
</imei1>
<imei1>
<LAT>2</LAT>
</imei1>
<imei2>
<LAT>3</LAT>
</imei2>
<imei4>
<LAT>4</LAT>
</imei4>
</Test>
我得到的结果是:
<Test>
<imei1>
<LAT>1</LAT>
</imei1>
<imei1>
<LAT>1</LAT>
</imei1>
<imei1>
<LAT>1</LAT>
</imei1>
<imei1>
<LAT>1</LAT>
</imei1>
<imei2>
<LAT>1</LAT>
</imei2>
<imei2>
<LAT>1</LAT>
</imei2>
<imei2>
<LAT>1</LAT>
</imei2>
<imei2>
<LAT>1</LAT>
</imei2>
相同的值重复并循环两次,是否输入了错误的xpath。第一个循环正确执行了预期的两倍,在简化表达式imei1和imei2中可以看到,但是第二个循环执行了预期结果计数的两倍,并给出相同的结果。
答案 0 :(得分:1)
由于您随意使用//
,因此您的内部说明是
<xsl:for-each select="//p:root/r:Entries/p:root">
将处理整个XML文档中的所有 r:Entries/p:root
个节点。而且由于它嵌套在外部:
<xsl:for-each select="//p:root/r:Entries">
它将实例化两次,对于XML中的每个r:Entries
节点一次。每个节点经过两次处理,结果节点的数量是开始时的两倍。
类似地,您:
<xsl:value-of select="//*[local-name()='LAT']"/>
选择本地名称为"LAT"
的XML文档中的所有节点-在XSLT 1.0中,xsl:value-of
将始终返回其中第一个的值。 / p>
值得一提的另一点:由于您已经声明了xmlns:p="test1"
和xmlns:r="test2"
(如您所愿),因此可以使用{{ 1}}。
最后,请勿在文字结果元素就足够的地方使用*[local-name()='LAT']
:例如而不是p:LAT
写xsl:element
。