首页 文章

XSLT无法为for-each找到XPATH

提问于
浏览
0

我正在尝试调试与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 =“http://www.w3.org/TR/xhtml1/strict”命名空间,一切似乎都运行良好,我能够进入循环 . 我不确定如何在不删除xmlns =“http://www.w3.org/TR/xhtml1/strict”命名空间的情况下解决此问题 .

1 回答

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

相关问题