我正在尝试调试与xpath相关的问题。我在我的XSLT中创建了一个变量$ MetaData,分配了一个xml文档,但由于某些原因,foreach循环无法找到它的子节点而且我无法进入foreach循环。
XSLT:
<!-- language: lang-xslt -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:variable name="_MetaData">
<MetaData>
<EmployeeId>1233</EmployeeId>
<EmployeeName>abcd</EmployeeName>
</MetaData>
</xsl:variable>
<xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"></xsl:variable>
<xsl:template match="*|@*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()='MetaDataTag']">
<xsl:copy>
<MetaData VocabularyOwner="acme.com" Vocabulary="MetaData">
<xsl:for-each select="$MetaData//MetaData/*">
<xsl:element name="Occurrence">
<xsl:attribute name="Id">
<xsl:value-of select="local-name(.)"/>
</xsl:attribute>
<xsl:attribute name="Value">
<xsl:value-of select="string(.)"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</MetaData>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML:
<?xml version="1.0" encoding="utf-8" ?>
<Envelope>
<MetaDataTag />
</Envelope>
如果我删除xmlns xmlns =&#34; http://www.w3.org/TR/xhtml1/strict"命名空间,一切似乎工作正常,我能够进入循环。 我不确定如何在不删除xmlns =&#34; http://www.w3.org/TR/xhtml1/strict"命名空间。
答案 0 :(得分:1)
如果在XSLT中定义默认命名空间,则变量中的节点将位于该命名空间中。 Xpath没有默认命名空间,因此$MetaData//MetaData/*
与{http://www.w3.org/TR/xhtml1/strict}MetaData
元素节点不匹配。
一种解决方案是使用local-name()
忽略名称空间。
`$MetaData//*[local-name() = 'MetaData']/*`
或者您可以为Xpath表达式定义(附加)前缀...
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/TR/xhtml1/strict">
...
</xsl:stylesheet>
...并在表达式中使用它。
`$MetaData//xhtml:MetaData/*`
但是标签在XHTML命名空间中无效,因此最好在空命名空间中创建数据元素:
<xsl:variable name="_MetaData">
<MetaData xmlns="">
<EmployeeId>1233</EmployeeId>
<EmployeeName>abcd</EmployeeName>
</MetaData>
</xsl:variable>
<xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"/>
或者为它们定义一个特定的命名空间......
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:data="urn:data">
<xsl:variable name="_MetaData">
<data:MetaData>
<data:EmployeeId>1233</data:EmployeeId>
<data:EmployeeName>abcd</data:EmployeeName>
</data:MetaData>
</xsl:variable>
<xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"/>
...
</xsl:stylesheet>
在表达式中使用:
$MetaData//data:MetaData/*