带有append和root元素名称空间的XSLT标识转换

时间:2013-04-12 07:34:22

标签: xslt xslt-1.0 xml-namespaces

我正在尝试创建一个XSLT库,用于通过少量更改传递大部分XML数据内容的常见任务。

包含文件目前看起来像这样(pass-through.xslt):

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

  <!-- change default behaviour to copying all attributes and nodes -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- copy element but add a child node -->
  <xsl:template name="append">
    <xsl:param name="element"/>
    <xsl:param name="appendage"/>
    <xsl:element name="{name($element)}">
      <xsl:copy-of select="$element/namespace::*"/>
      <xsl:copy-of select="$element/@*"/>
      <xsl:apply-templates select="$element/node()"/>
      <xsl:copy-of select="$appendage"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

然后你可以创建一个包含它的样式表,而不必担心一遍又一遍地重复自己(调用样式表)。

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

  <xsl:include href="pass-through.xslt"/>

  <!-- only worry about the transform you want -->
  <xsl:template match="element-to-be-modified">
  ...
  </xsl:template>

</xsl:stylesheet>

如果您只想在文档中添加元素,请调用“append”。

<xsl:stylesheet 

对于我要附加的元素上的命名空间,除了。如果我在根元素上有一个带有命名空间的XML文件,它就会说明前缀没有命名空间绑定。如果我将根元素的名称空间添加到库中,那么它很高兴,但是如果你必须为每次使用修改它,那就会破坏库的目的。

我很乐意将xmlns:ns =“uri”添加到调用样式表中,但是命名空间声明的范围似乎只扩展到样式表 - 而不是到包含的样式表中“追加”模板是。

我希望能够改变

<ns:root xmlns:ns="http://example/namespace">
  <ns:child>old child</ns:child>
</ns:root>

<ns:root xmlns:ns="http://example/namespace">
  <ns:child>old child</ns:child>
  <ns:child>new child!</ns:child>
</ns:root>

每次都不必包含身份变换样板。我已经尝试了各种各样的东西,包括在“append”模板中的元素中添加了namespace =“{namespace-uri()}”,但似乎没有任何东西保留附加到的元素上的名称空间前缀。

2 个答案:

答案 0 :(得分:1)

替换

<xsl:element name="{name($element)}">

通过

<xsl:element name="{name($element)}" namespace="{namespace-uri($element)}">

答案 1 :(得分:0)

如果,当你打电话给你的命名模板&#34;追加&#34;您已经定位在要复制/修改的元素上,那么实际上不需要将当前元素作为参数传递。你可以在这里使用 xsl:copy

 <xsl:template name="append">
    <xsl:param name="appendage"/>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:copy-of select="$appendage"/>
    </xsl:copy>
 </xsl:template>

在您的示例中,您只需将其称为

<xsl:template match="ns:root">
   <xsl:call-template name="append">
       <xsl:with-param name="appendage"><ns:child>new child!</ns:child></xsl:with-param>
   </xsl:call-template>
</xsl:template>

使用 xsl:copy 应该复制您的元素并保留命名空间。