XSLT 将新元素添加到 XML 的根元素 [英] XSLT to add new elements to the root element of an XML

查看:35
本文介绍了XSLT 将新元素添加到 XML 的根元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 XML 文档的末尾添加几个元素,就在关闭根节点之前,我正在使用 XSL 进行转换.

源 XML 可以包含任何节点、子节点等,这无关紧要.其中的所有内容都应该复制到转换后的文档中,另外还需要添加一些其他元素.

我对 XSL、XSLT 和 XPath 完全陌生,所以我无疑会犯错误.

我所有的 XSL 都是这样的:

<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/><!-- 尝试过的指令--></xsl:stylesheet>

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

<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy><my-el></my-el></xsl:模板>

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

在阅读了一些关于 XSLTXPath,我试过:

<xsl:copy-of select="."></xsl:copy-of><我的元素/></xsl:模板>

但是它在根元素的结束标记之后添加了.

你能帮我吗?

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

这是源 web.xml 文件:

<display-name>我的项目</display-name><欢迎文件列表>索引.jsp</welcome-file-list></web-app>

我想实现类似于这个问题中所问的问题,但新节点必须是添加到根元素(即参见对该问题答案的评论).

解决方案

试试这个方法?

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/><xsl:strip-space elements="*"/><!-- 身份变换--><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:模板><!-- 匹配未知名称的根元素--><xsl:template match="/*"><xsl:copy><xsl:apply-templates select="@*|node()"/><!-- 在最后添加一个新元素--><my-el>我的内容</my-el></xsl:copy></xsl:模板></xsl:stylesheet>

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

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/><xsl:strip-space elements="*"/><!-- 匹配未知名称的根元素--><xsl:template match="/*"><xsl:copy><xsl:copy-of select="@*|node()"/><!-- 在最后添加一个新元素--><my-el>我的内容</my-el></xsl:copy></xsl:模板></xsl:stylesheet>

<小时>

注意:

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

<xsl:element name="my-el" namespace="{namespace-uri()}">我的内容</xsl:element>

代替:

我的内容

<小时>

<块引用>

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

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

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/><xsl:strip-space elements="*"/><!-- 匹配已知名称的根元素--><xsl:template match="/jve:web-app"><xsl:copy><xsl:copy-of select="@*|node()"/><!-- 在最后添加一个新元素--><my-el>我的内容</my-el></xsl:copy></xsl:模板></xsl:stylesheet>

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

 <jve:my-el>我的内容</jve:my-el>

或者你可以这样做:

 <my-el xmlns="http://java.sun.com/xml/ns/javaee">我的内容</my-el>

I want to add a couple of elements at the end of an XML document, right before the closing of the root node, and I'm using an XSL to do the transformation.

The source XML can contain any node, subnode, etc, that doesn't matter. Everything in it should be copied to the transformed document, plus some other elements have to be added.

I'm totally new to XSL, XSLT and XPath, so I'm undoubtedly doing mistakes.

All my XSL's are like this:

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

This is what I found and tried, but with no success.

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

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

I've read that's the identity template, so I thought I'd use it to copy everything plus an additional element; but this adds <my-el></my-el> inside each element of the source document.

After reading up a little of w3schools tutorials about XSLT and XPath, I tried with:

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

But it adds <my-elem /> after the closing tag of the root element.

Can you help me out?

Background: I'm playing with the xml-maven-plugin to add some configuration to a web application web.xmlfile, triggered by a profile. I want that all of the existing XML in the file be copied to the output document, plus I want to add some (static will be enough for now) elements to it.

Here's the source web.xml file:

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

I want to achieve something like what's been asked in this question, but the new nodes have to be added to the root element (i.e. see a comment to that question answer).

解决方案

Try it this way?

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

If all you ever want to do is add the new element/s, then you could shorten this to:

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


Note:

In your example input, the root element - and by inheritance, all of its child nodes - is in a namespace. If you want the added element/s to be in the same namespace, use:

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

instead of:

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


Edit:

why doesn't it work if I put <xsl:template match="/web-app"> (<web-app/> is the document root node) instead of <xsl:template match="/*">?

That too is the result of the root element being in a namespace. In order to address it by name, you need to assign a prefix to the namespace and use it in the XPpath expression selecting the node:

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

Once you have defined the prefix, you can also use it to place the added element/s in the namespace bound to the prefix:

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

Alternatively you could do:

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

这篇关于XSLT 将新元素添加到 XML 的根元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆