Adding namespace in inner parent group in xslt v2.

2019-09-15 10:24发布

问题:

I tried all the codes I've seen in the internet with relevant requirement as I have. However, in my case, I also need to populate the namespace within the inner parent group. My XSLT didn't work as expected. Can anyone help me with this? Thank you.

XSLT CODE:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="Section">
    <Section xmlns="www.hdgd.co">
        <xsl:apply-templates select="@*|node()"/>
    </Section>
</xsl:template>

INPUT:

<Record xmlns="www.hdgd.co">
<Data>
    <Section>
        <ID>1234DFD57</ID>
    </Section>
</Data>

EXPECTED OUTPUT:

<Record>
<Data>
    <Section xmlns="www.hdgd.co">
        <ID>1234DFD57</ID>
    </Section>
</Data>

GENERATED OUTPUT:

<Record xmlns="www.hdgd.co">
<Data>
    <Section>
        <ID>1234DFD57</ID>
    </Section>
</Data>

回答1:

You seem to be unaware of namespaces inheritance. The default namespace declaration at the Record root element is applied to all elements of the input document. Therefore, in order to achieve the requested result, you must take all elements out of their namespace, while leaving the Section element and its descendants unprocessed:

XSLT 2.0

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

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

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

</xsl:stylesheet> 

Added:

If your input has attributes that need copying, then change the first template to:

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>


回答2:

That sounds as if you want to remove the namespace from Record and Data:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xpath-default-namespace="www.hdgd.co">

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

    <xsl:template match="Record | Data">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
</xsl:transform>

http://xsltransform.net/bEzjRJM gives

<?xml version="1.0" encoding="UTF-8"?><Record>
<Data>
    <Section xmlns="www.hdgd.co">
        <ID>1234DFD57</ID>
    </Section>
</Data>
</Record>


标签: xslt xslt-2.0