具有附加和根元素名称空间的XSLT标识转换

具有附加和根元素名称空间的XSLT标识转换,xslt,xslt-1.0,xml-namespaces,Xslt,Xslt 1.0,Xml Namespaces,我正在尝试创建一个XSLT库,用于通过小改动传递XML数据的大部分内容的常见任务 include文件当前如下所示(pass-through.xslt): 然后,您可以创建一个包含它的样式表,而不必担心反复重复(调用样式表) ... 如果您只想向文档中添加一个元素,那么请调用“append” 替换 <xsl:element name="{name($element)}"> 借 更换 <xsl:element name="{name($element)}">

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

include文件当前如下所示(pass-through.xslt):


然后,您可以创建一个包含它的样式表,而不必担心反复重复(调用样式表)


...
如果您只想向文档中添加一个元素,那么请调用“append”

替换

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


更换

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


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

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

我确实尝试过使用
,但是附件一直被附加到输出的末尾并破坏它。我最终发现这是因为我匹配的是文档的根(
match='/'
),而不是根文档元素(
match='ns:root'
)。在没有上下文的情况下匹配根文档元素的问题在于,理论上它可能会匹配源XML中更深层的另一个同名元素。在
match='/ns:root'
上进行匹配应该可以解决这个问题。我应该发布最终的XSLT文件,还是假设人们可以从答案中自己找到答案?我假设人们可以找到主要问题。顺便说一句,您也可以执行
来匹配根元素,这样,如果根元素名称发生变化,它就可以应付。我确实尝试过使用
,但附件一直被附加到输出的末尾,并将其破坏。我最终发现这是因为我匹配的是文档的根(
match='/'
),而不是根文档元素(
match='ns:root'
)。在没有上下文的情况下匹配根文档元素的问题在于,理论上它可能会匹配源XML中更深层的另一个同名元素。在
match='/ns:root'
上进行匹配应该可以解决这个问题。我应该发布最终的XSLT文件,还是假设人们可以从答案中自己找到答案?我假设人们可以找到主要问题。顺便说一句,您也可以做
来匹配根元素,然后如果根元素的名称发生变化,它就可以应付。我确实尝试过(请参见问题的结尾),出于某种原因,它在保留名称空间前缀方面对我不起作用。当我在你建议后再次尝试时,它确实起了作用。(感谢Saxon btw)我真的应该使用,正如下面@TimC所建议的。我确实尝试过(见问题的结尾),出于某种原因,它在保留名称空间前缀方面不起作用。当我在你建议后再次尝试时,它确实起了作用。(感谢萨克森顺便说一句)我真的应该使用,正如下面@TimC所建议的。
<xsl:element name="{name($element)}" namespace="{namespace-uri($element)}">
 <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>