Xml 如何将xslt中的参数用作XPath?

Xml 如何将xslt中的参数用作XPath?,xml,xslt,xpath,parameters,xalan,Xml,Xslt,Xpath,Parameters,Xalan,我想向xml文档中添加一个元素,并将该元素的路径作为参数传递 sample.xml文件: <?xml version="1.0"?> <stuff> <element1> <foo>2</foo> <bar/> </element1> <element2> <subelement/> <bar/> </element2> <el

我想向xml文档中添加一个元素,并将该元素的路径作为参数传递

sample.xml文件:

<?xml version="1.0"?>
<stuff>
  <element1>
    <foo>2</foo>
<bar/>
  </element1>
  <element2>
<subelement/>
<bar/>
   </element2>
   <element1>
     <foo/>
 <bar/>
   </element1>
 </stuff>
我想要以下结果:

<?xml version="1.0"?>
<stuff>
  <element1>
    <foo>2</foo>
    <bar/>
    <addedElement/>
  </element1>
  <element2>
<subelement/>
<bar/>
   </element2>
   <element1>
     <foo/>
 <bar/>
     <addedElement/>
   </element1>
 </stuff>
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>

已替换硬编码路径的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>


感谢您的帮助

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

<xsl:template match="*[name()=$myparam]/*[last()]">

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

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

以下是如何使用XSLT 1.0做到这一点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="n" select="'element1'"/>

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

<xsl:template match="*/*[last()]">
  <xsl:choose>
    <xsl:when test="local-name(..) = $n">
      <xsl:copy-of select="."/>
      <addedElement></addedElement>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>


您的意思是变量/参数不是有效的XPath表达式吗?但是,我无法使它与您的解决方案一起工作。首先,XSLT1.0根本不允许在匹配模式中使用变量/参数。XSLT2.0确实允许这样做,但如果使用Xalan(XSLT1.0处理器),就不能使用XSLT2.0特性。其次,如果有一个字符串类型的变量或参数具有元素名,则不能使用它动态构造XPath表达式。无论是在XPath还是在其他语言中,变量/参数都不是这样工作的。如果变量/参数值是字符串类型,那么您可以在任何允许使用字符串的地方使用它,就像Tim所做的那样。谢谢Martin,您知道任何基于命令行的XSLT 2.0处理器吗?Saxon 9()、格式塔()、AltovaXML工具()都可以从命令行使用。我很困惑,我可以使它与蒂姆的解决方案都与Xalan和Saxon 9。对于Xalan,它不起作用,因为我必须在命令行中对参数的值使用单引号。由于Tim的解决方案也适用于Xalan,因此我认为Tim的解决方案与XSLT1.0兼容。顺便说一下,我不确定我是否理解你的第一句话。如果我错了,请纠正我:XSLT2.0允许在匹配模式中使用变量/参数,但它们不能用于构造XPath表达式?那么,如何在匹配模式中使用它们呢?
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:if test="local-name() = $myparam">
            <addedElement/>
        </xsl:if>
    </xsl:copy>
</xsl:template>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="n" select="'element1'"/>

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

<xsl:template match="*/*[last()]">
  <xsl:choose>
    <xsl:when test="local-name(..) = $n">
      <xsl:copy-of select="."/>
      <addedElement></addedElement>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>