I want to change an xml's namespace url values. I have an xml like the following
<catalog xmlns="http://someurl"
xmlns:some="http://someurl2"
xsi:schemaLocation="http://someurl some.3.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>
<name>Columbia</name>
</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
I am using identity transformation. Is there any way I can change the text in the namespace ursl? For example I want to change the urls 'http://someurl' to 'http://someur2' and 'http://so开发者_高级运维meurl some.3.0.xsd' to 'http://someurl some.4.0.xsd'
This should do it:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
xmlns:old="http://someurl" exclude-result-prefixes="old">
<!-- Identity transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- replace namespace of elements in old namespace -->
<xsl:template match="old:*">
<xsl:element name="{local-name()}" namespace="http://someurl2">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- replace xsi:schemaLocation attribute -->
<xsl:template match="@xsi:schemaLocation">
<xsl:attribute name="xsi:schemaLocation">http://someurl some.4.0.xsd</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
With the sample input, this gives:
<?xml version="1.0" encoding="utf-8"?>
<catalog xmlns="http://someurl2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://someurl some.4.0.xsd">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>
<name>Columbia</name>
</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
Explanation:
The last two templates, added to the identity transform, are more specific and therefore take higher default priority than the identity template. They override the identity template for elements in the "old" namespace, and xsl:schemaLocation attributes, respectively.
The template for "old:*" outputs an element with the same local-name as the one it's replacing (i.e. the name without the namespace), and gives it the new desired namespace.
Happily, the XSLT processor (or more properly, the serializer; I'm using Saxon 6.5.5 for my test) decided to make this new namespace the default, so it added a default namespace declaration for it to the output root element. We didn't ask it to do that, and theoretically it shouldn't matter whether this new namespace is the default or uses a prefix. But you seem to want it to be the default so that worked out well.
精彩评论