2016-05-16 55 views
0

我正在尝试调试与xpath相关的问题。我在我的XSLT中创建了一个变量$ MetaData,用于分配一个xml文档,但由于某种原因,foreach循环无法找到它的子项,我无法进入foreach循环。XSLT无法找到每个的XPATH

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 = “http://www.w3.org/TR/xhtml1/strict” 命名空间,一切似乎都工作正常,我能够进入循环。 我不知道如何解决此问题,而不删除xmlns =“http://www.w3.org/TR/xhtml1/strict”命名空间。

回答

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/*