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

wat*_*ery 1 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>
Run Code Online (Sandbox Code Playgroud)

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

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

    <my-el></my-el>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

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

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

<xsl:template match="/">
<xsl:copy-of select="."></xsl:copy-of>
<my-elem />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

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

你能帮我吗?

背景:我正在玩,以xml-maven-plugin通过配置web.xml文件触发向Web应用程序文件中添加一些配置。我希望将文件中所有现有的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>
Run Code Online (Sandbox Code Playgroud)

我想实现类似此问题的要求,但是必须将新节点添加到根元素(即,查看对该问题答案的评论)。

mic*_*57k 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>
Run Code Online (Sandbox Code Playgroud)

如果所有你曾经想要做的就是添加新元素/秒,那么你可以缩短这:

<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>
Run Code Online (Sandbox Code Playgroud)

注意:

在示例输入中,根元素(并通过继承获得其所有子节点)位于命名空间中。如果希望添加的元素在同一名称空间中,请使用:

<xsl:element name="my-el" namespace="{namespace-uri()}">my content</xsl:element>
Run Code Online (Sandbox Code Playgroud)

代替:

<my-el>my content</my-el>
Run Code Online (Sandbox Code Playgroud)

编辑:

如果我放<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>
Run Code Online (Sandbox Code Playgroud)

定义前缀后,还可以使用它将添加的元素放入绑定到该前缀的名称空间中:

    <!-- add a new element at the end -->
    <jve:my-el>my content</jve:my-el>   
Run Code Online (Sandbox Code Playgroud)

或者,您可以执行以下操作:

    <!-- add a new element at the end -->
    <my-el xmlns="http://java.sun.com/xml/ns/javaee">my content</my-el> 
Run Code Online (Sandbox Code Playgroud)