问题
I'm trying to make a transformation for an XML document but i cannot find a solution since i do not know XSLT. I have the XML document:
<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='http://whatever/test.xsd'>
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
and i want to produce:
<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml">
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
(Consider that xsi:noNamespaceSchemaLocation="..." has already excluded using another XSLT before this one).
Can someone help me find a solution?
The XSLT used to eliminate the xsi:noNamespaceSchemaLocation is:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@xsi:noNamespaceSchemaLocation"/>
</xsl:stylesheet>
回答1:
Please give this a try:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xsi"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(. = 'http://www.w3.org/2001/XMLSchema-instance')]" />
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@xsi:noNamespaceSchemaLocation"/>
</xsl:stylesheet>
回答2:
I have got two options:
XSLT1:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>
Output1:
<?xml version="1.0" encoding="utf-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
XSLT2:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>
Output2:
<?xml version="1.0" encoding="utf-8"?>
<addresses>
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
回答3:
Your problem is that when copying an element node <xsl:copy>
implicitly copies namespace nodes that are in scope at that point in the document. Try adding an extra template for element nodes to specifically exclude the xsi
namespace:
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(name() = 'xsi')]" />
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
If your xsl:stylesheet
has an xmlns:xsi
then you may also find you need to add exclude-result-prefixes="xsi"
as suggested in this answer.
This should prevent the xsi namespace from appearing in the output if it is there solely because it was copied from the input, though the serialiser may re-introduce it if required to make the output well formed (i.e. if it needs to output an element or attribute in that namespace).
来源:https://stackoverflow.com/questions/14188119/remove-a-specific-xmlns-from-root-element-of-xml