XSLT to add new elements to the root element of an XML

前端 未结 1 782
攒了一身酷
攒了一身酷 2021-01-25 03:51

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 X

相关标签:
1条回答
  • 2021-01-25 04:02

    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> 
    
    0 讨论(0)
提交回复
热议问题