XSLT将新元素添加到XML的根元素

时间:2014-09-21 08:07:25

标签: xml xslt xpath

我希望在关闭根节点之前在XML文档的末尾添加几个元素,并且我使用XSL进行转换。

源XML可以包含任何不重要的节点,子节点等。其中的所有内容都应该复制到转换后的文档中,还必须添加其他一些元素。

我对XSL,XSLT和XPath都很陌生,所以我毫无疑问会犯错误。

我所有的XSL都是这样的:

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

<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes" />

    <!-- tried directives -->

</xsl:stylesheet>

这是我发现并尝试过的,但没有成功。

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

    <my-el></my-el>
</xsl:template>

我已经读过这个身份模板,所以我想我会用它来复制所有内容以及一个额外的元素;但是这会在源文档的每个元素中添加<my-el></my-el>

在阅读了关于XSLTXPath的一些w3schools教程后,我尝试了:

<xsl:template match="/">
<xsl:copy-of select="."></xsl:copy-of>
<my-elem />
</xsl:template>

但是它在根元素的结束标记之后添加了<my-elem />

你可以帮帮我吗?

背景:我正在使用xml-maven-plugin将一些配置添加到由配置文件触发的Web应用程序web.xml文件中。我希望文件中的所有现有XML都被复制到输出文档中,而且我想在其中添加一些(静态就足够了)元素。

这是源web.xml文件:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">

<display-name>My Project</display-name>
    <welcome-file-list>
        index.jsp
    </welcome-file-list>
</web-app>

我希望在this question中实现类似的内容,但必须将新节点添加到根元素(即参见a comment to that question answer)。

1 个答案:

答案 0 :(得分:5)

以这种方式试试吗?

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<!-- match the root element of unknown name -->
<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <!-- add a new element at the end -->
        <my-el>my content</my-el>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果所有你想要做的是添加新元素,那么你可以缩短为:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- match the root element of unknown name -->
<xsl:template match="/*">
    <xsl:copy>
        <xsl:copy-of select="@*|node()"/>
        <!-- add a new element at the end -->
        <my-el>my content</my-el>   
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

注意:

在您的示例输入中,根元素 - 以及通过继承,其所有子节点 - 位于命名空间中。如果要将添加的元素放在同一名称空间中,请使用:

<xsl:element name="my-el" namespace="{namespace-uri()}">my content</xsl:element>

而不是:

<my-el>my content</my-el>

编辑:

  

如果我放<xsl:template match="/web-app">,为什么它不起作用   (<web-app/>是文档根节点)而不是<xsl:template match="/*">

这也是根元素在命名空间中的结果。为了按名称解决它,您需要为命名空间分配前缀,并在选择节点的XPpath表达式中使用它:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jve="http://java.sun.com/xml/ns/javaee"
exclude-result-prefixes="jve">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- match the root element of known name -->
<xsl:template match="/jve:web-app">
    <xsl:copy>
        <xsl:copy-of select="@*|node()"/>
        <!-- add a new element at the end -->
        <my-el>my content</my-el>   
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

一旦定义了前缀,您还可以使用它将添加的元素放在绑定到前缀的名称空间中:

    <!-- add a new element at the end -->
    <jve:my-el>my content</jve:my-el>   

或者你可以这样做:

    <!-- add a new element at the end -->
    <my-el xmlns="http://java.sun.com/xml/ns/javaee">my content</my-el>