0
votes

i thought this would be simple but now i spent about 4 hours on this problem. All i want to do is change the default namespace of this XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<scenarios xmlns="http://my.url/xmlns/scenarios/v1.0.0">
    <scenarios>
        <scenario id="1" name="00_reset" active="true">
            <events>
                <sensorevent id="1" name="resetButtonEvent">
                    <sensors>
                        <sensor deviceid="46"/>
                    </sensors>
                </sensorevent>
            </events>
        </scenario>
    </scenarios>
    <systemstates>
        <systemstate id="1" default="true" name="00_visitor_reset" display="true" publish="true" type="BOOLEAN"/>
    </systemstates>
</scenarios>

"v1.0.0" should be changed to "v1.1.0". But all i could come up with is this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:old="http://my.url/xmlns/scenarios/v1.0.0" 
xmlns:new="http://my.url/xmlns/scenarios/v1.1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="http://my.url/xmlns/scenarios/v1.1.0">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

which produces:

<?xml version="1.0" encoding="UTF-8"?><ns0:scenarios xmlns:ns0="http://my.url/xmlns/scenarios/v1.1.0">
    <ns1:scenarios xmlns:ns1="http://my.url/xmlns/scenarios/v1.1.0">
        <ns2:scenario xmlns:ns2="http://my.url/xmlns/scenarios/v1.1.0" id="1" name="00_reset" active="true">
            <ns3:events xmlns:ns3="http://my.url/xmlns/scenarios/v1.1.0">
                <ns4:sensorevent xmlns:ns4="http://my.url/xmlns/scenarios/v1.1.0" id="1" name="resetButtonEvent">
                    <ns5:sensors xmlns:ns5="http://my.url/xmlns/scenarios/v1.1.0">
                        <ns6:sensor xmlns:ns6="http://my.url/xmlns/scenarios/v1.1.0" deviceid="46"/>
                    </ns5:sensors>
                </ns4:sensorevent>
            </ns3:events>
        </ns2:scenario>
    </ns1:scenarios>
    <ns7:systemstates xmlns:ns7="http://my.url/xmlns/scenarios/v1.1.0">
        <ns8:systemstate xmlns:ns8="http://my.url/xmlns/scenarios/v1.1.0" id="1" default="true" name="00_visitor_reset" display="true" publish="true" type="BOOLEAN"/>
    </ns7:systemstates>
</ns0:scenarios>

which is not really what i want, because the only thing that should change is the namespace declaration in the root element. How can i change the default namespace from http://my.url/xmlns/scenarios/v1.0.0 to http://my.url/xmlns/scenarios/v1.1.0 using XSLT1.0 without adding prefixes?

3

3 Answers

0
votes

XSLT 1.0 allows the XSLT processor to choose any namespace prefix it likes, so this output is conformant, but very unfriendly. In XSLT 2.0 the processor is required to choose the prefix you ask for unless there is a conflict, so this stylesheet should produce the output you want. So I think your choices are to run the code through an XSLT 2.0 processor, or through a more user-friendly XSLT 1.0 processor.

1
votes

Try

<xsl:stylesheet version="1.0" xmlns:old="http://my.url/xmlns/scenarios/v1.0.0" 
xmlns="http://my.url/xmlns/scenarios/v1.1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="old:*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

If that does not help then try a different XSLT 1.0 processor.

0
votes

I've now switched to Saxon as XSLT processor and it shows the desired output. I wanted to avoid additional dependencies but it seems that there is no other way. Thanks Martin Honnen and Michael Kay!