XSL Replace Namespace

2019-08-16 02:28发布

问题:

I have below XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:OrderChange ns0:transactionPurposeIndicator="Change" xmlns:ns0="http://www.api.org/pidXML">
<ns0:OrderChangeProperties>
<ns0:OrderChangeNumber>1</ns0:OrderChangeNumber>
<ns0:OrderChangeDate>2009-10-19</ns0:OrderChangeDate>
</ns0:OrderChangeProperties>
</ns0:OrderChange>

And i need to convert this to below format:

<?xml version="1.0" encoding="UTF-8"?>
<pidx:OrderChange pidx:transactionPurposeIndicator="Change"    xmlns:pidx="http://www.api.org/pidXML" xmlns="http://www.api.org/pidXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.api.org/pidXML Z:\integration\trunk\schemas\pidx\OrderChange_1-2.xsd">
<pidx:OrderChangeProperties>
<pidx:OrderChangeNumber>1</pidx:OrderChangeNumber>
<pidx:OrderChangeDate>2009-10-19</pidx:OrderChangeDate>
</pidx:OrderChangeProperties>
</pidx:OrderChange>

Can someone please let me know the XSL which would do this transformation. I have tried several XSL tranformations but not able to achieve it. Really appreciate all the help

Thanks

回答1:

We are working with a Cloud based application and their requirements are pretty stringent. They need the XML specifically in the format i mentioned above.

Well, it should make no difference whatsoever. If it does, then "they" are doing it wrong.

Also, if you check the tag in the to-be format (second code) it has several more "namespaces" defined than in as-is (first code) so i assumed i would need "namespace replacement" as well

Adding these is relatively trivial, and has nothing to do with changing the namespace prefix. Anyway, try the following:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://www.api.org/pidXML"
xmlns:pidx="http://www.api.org/pidXML"
exclude-result-prefixes="ns0"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="ns0:OrderChange">
    <pidx:OrderChange xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.api.org/pidXML Z:\integration\trunk\schemas\pidx\OrderChange_1-2.xsd">
        <xsl:apply-templates select="@*|node()"/>
    </pidx:OrderChange>
</xsl:template>

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

<xsl:template match="@*">
<xsl:attribute name="pidx:{local-name()}">
    <xsl:value-of select="." />
</xsl:attribute>
</xsl:template>

</xsl:stylesheet>  


回答2:

If the cloud based application insists on using particular namespace prefixes then you should ask some serious questions about the competence of the people running this service. That's really bad XML practice.

Officially, XSLT 1.0 gives you no control over the choice of namespace prefix in the output. It's not supposed to matter, so the spec lets implementations do what they like. In practice, however, in nearly all practical cases actual implementations will use the prefix you specify in the stylesheet; and in XSLT 2.0 this has become mandatory. So the solution from @michael.hor257k using

<xsl:element name="pidx:{local-name()}">

should do the trick in practice, even though it's not guaranteed.



标签: xslt