如何在xslt中使用参数作为XPath?

Dav*_*vid 12 xml xslt parameters xpath xalan

我想在xml文档中添加一个元素,我想将参数作为参数传递给元素.

sample.xml文件:

<?xml version="1.0"?>
<stuff>
  <element1>
    <foo>2</foo>
<bar/>
  </element1>
  <element2>
<subelement/>
<bar/>
   </element2>
   <element1>
     <foo/>
 <bar/>
   </element1>
 </stuff>
Run Code Online (Sandbox Code Playgroud)

使用:

xalan.exe -p myparam "element1" sample.xml addelement.xslt
Run Code Online (Sandbox Code Playgroud)

我想得到以下结果:

<?xml version="1.0"?>
<stuff>
  <element1>
    <foo>2</foo>
    <bar/>
    <addedElement/>
  </element1>
  <element2>
<subelement/>
<bar/>
   </element2>
   <element1>
     <foo/>
 <bar/>
     <addedElement/>
   </element1>
 </stuff>
Run Code Online (Sandbox Code Playgroud)

我已经设法编写addelement.xslt,当硬编码它的工作路径时,但是当我尝试在match属性中使用参数myparam时,我得到:

XPathParserException: A node test was expected.
pattern = '$myparam/*[last()]' Remaining tokens are:  ('$' 'myparam' '/' '*' '[' 'last' '(' ')' ']') (addelement.xslt, line 12, column 42)
Run Code Online (Sandbox Code Playgroud)

addelement.xslt

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="element1/*[last()]">
    <xsl:copy-of select="."/>
<addedElement></addedElement>
</xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

替换了硬编码路径的addelement.xslt

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="myparam"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="$myparam/*[last()]">
    <xsl:copy-of select="."/>
<addedElement></addedElement>
</xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助

Tim*_*m C 6

我认为您不能像编码那样在匹配模板中使用变量/参数.即使这样也行不通

<xsl:template match="*[name()=$myparam]/*[last()]">
Run Code Online (Sandbox Code Playgroud)

相反,请尝试将第一个匹配模板更改为如下,以便参数检查位于模板代码内,而不是作为匹配语句的一部分.

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:if test="local-name() = $myparam">
            <addedElement/>
        </xsl:if>
    </xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

  • 首先,XSLT 1.0根本不允许在匹配模式中使用变量/参数.XSLT 2.0确实允许它,但是如果使用Xalan,一个XSLT 1.0处理器,则不能使用XSLT 2.0功能.其次,如果你有一个带有元素名称的string类型的变量或参数,那么就不能用它来动态地构造XPath表达式.这不是变量/参数在XPath或其他语言中的工作方式.如果变量/参数值是string类型,那么你可以在允许字符串的任何地方使用它,就像Tim所做的那样. (3认同)