1

我正在尝试创建一个 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>

如果您只想将元素添加到文档中,请调用“追加”。

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

无需每次都包含身份转换样板。我尝试了各种各样的东西,包括在“附加”模板中的元素中添加一个命名空间=“{namespace-uri()}”,但似乎没有任何东西可以保留附加到的元素上的命名空间前缀。

4

2 回答 2

1

代替

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

经过

<xsl:element name="{name($element)}" namespace="{namespace-uri($element)}">
于 2013-04-12T07:50:57.970 回答
0

如果,当您调用命名模板“附加”时,您已经定位在要复制/修改的元素上,那么确实不需要将当前元素作为参数传递。你可以在这里使用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应该复制您的元素并保留命名空间。

于 2013-04-12T12:32:17.673 回答