I have the following XML which can appear in either form in my XML Document:
<Message xsi:schemaLocation="http://www.location.com StructureFile.xsd" xmlns=http://www.thenamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
or
<Message xmlns="http://www.thenamespace.com">
and I need the output to be:
<Message xmlns="http://www.theNEWnamespace.com">
I currently have this template to handle the shorter version of the two xml possibilities:
<xsl:template match="*">
<xsl:element name="{name()}" namespace="http://www.theNEWnamespace.com">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
However this does not remove the SchemeLocation or xmlns:xsi parts of the xml if they are in existance.
How would I go about adapting the above to handle both possibilities.
Cheers,
Edit: XML structure:
<?xml version="1.0" encoding="utf-8"?>
<Message xsi:schemaLocation="http://www.location.com StructureFile.xsd" xmlns="http://www.thenamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<Info></Info>
</Header>
</Message>
Here is a complete transformation producing the wanted result :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.thenamespace.com">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="x:Message">
<xsl:element name="{name()}" namespace="http://www.theNEWnamespace.com">
<xsl:copy-of select="@*[not(name() = 'xsi:SchemaLocation')]"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document (none provided!):
<t>
<Message
xsi:SchemaLocation="http://www.location.com StructureFile.xsd"
xmlns="http://www.thenamespace.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</t>
the wanted, correct result is produced:
<Message xmlns="http://www.theNEWnamespace.com"/>
First of all, in the XSLT/XPath data model only the xsi:schemaLocation
is an attribute. If you don't want to copy that attribute or any attributes at all, well, then don't do <xsl:copy-of select="@*"/>
because there you explicitly copy all attributes. Or if you want to selectively specify which attributes not to copy then instead of the <xsl:copy-of select="@*"/>
put in <xsl:apply-templates select="@*"/>
, then write one template for copying attributes and then templates for those attributes you don't want to copy eg
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="@xsi:schemaLocation"/>
As for xmlns:xsi
, that is a namespace declaration which in the XSLT/XPath data model is not an attribute. And if all you do for element nodes is the template you have shown then I don't see how that namespace should be copied through to the output.
If you however define namespaces in the stylesheet too then you need exclude-result-prefixes="xsi"
on the xsl:stylesheet
element.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.