I met issue when trying to remove namespace in element tag. It is always display in element tag, but other tag is not display I also use exclude-result-prefixes but it is not work. I dont know that is the reason Please help to support to check this issue and explain how does it work Thank you
XML sample
<STATUS
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="MOM.Production">
<A>
<A1 CODE="11111" DESC="RAW" >
<A2>
<A2_ITEM NUMBER="DUM20000001" REVISION="01" />
<A2_ITEM NUMBER="DUM20000002" REVISION="01" />
</A2>
</A1>
<A1 CODE="22222" DESC="POI" >
<A2>
<A2_ITEM NUMBER="DUM20000003" REVISION="01" />
<A2_ITEM NUMBER="DUM20000004" REVISION="01" />
</A2>
</A1>
</A>
<B>
<B1 ID="A10" >A101</B1>
<B1 ID="A12" >A121</B1>
<B1 ID="A13" >A132</B1>
</B>
</STATUS>
XSLT sample
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mom="MOM.Production" exclude-result-prefixes="mom" >
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />
<xsl:template match="/mom:STATUS">
<xsl:element name="Telegram">
<xsl:element name="Body">
<xsl:apply-templates select="/mom:STATUS/mom:A"/>
<xsl:apply-templates select="/mom:STATUS/mom:B"/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="/mom:STATUS/mom:A">
<xsl:element name="A">
<xsl:copy-of select="*" />
</xsl:element>
</xsl:template>
<xsl:template match="/mom:STATUS/mom:B">
<xsl:element name="Options">
<xsl:for-each select="/mom:STATUS/mom:B/mom:B1">
<xsl:element name="Option">
<xsl:attribute name="code">
<xsl:value-of select="text()"/>
</xsl:attribute>
<xsl:attribute name="family">
<xsl:variable name="n">
<xsl:number/>
</xsl:variable>
<xsl:value-of select="$n - 1"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Expect result
<Telegram>
<Body>
<A>
<A1
CODE="11111"
DESC="RAW">
<A2>
<A2_ITEM NUMBER="DUM20000001" REVISION="01"/>
<A2_ITEM NUMBER="DUM20000002" REVISION="01"/>
</A2>
</A1>
<A1
CODE="22222"
DESC="POI">
<A2>
<A2_ITEM NUMBER="DUM20000003" REVISION="01"/>
<A2_ITEM NUMBER="DUM20000004" REVISION="01"/>
</A2>
</A1>
</A>
<Options>
<Option code="A101" family="0"/>
<Option code="A121" family="1"/>
<Option code="A132" family="2"/>
</Options>
</Body>
</Telegram>
CodePudding user response:
The attribute exclude-result-prefixes only affects the namespaces generated by a literal result element, and there are no literal result elements in your stylesheet.
The xsl:copy-of
instruction copies element nodes unchanged from the input to the output. "Unchanged" means that the fully qualified name of the element (local-name plus namespace) is unchanged from the input. To change the names of the elements, you need to process the input recursively using apply-templates to change each element as it is encountered.
CodePudding user response:
I believe you are missing the fact that a default namespace declaration applies to all elements in its scope - in your case, to all elements in the entire XML document.
That means you cannot copy any elements; instead, you must recreate every element as a new element in no-namespace (this is equivalent to renaming all elements).
Try:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mom="MOM.Production"
exclude-result-prefixes="mom">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/mom:STATUS">
<Telegram>
<Body>
<xsl:apply-templates/>
</Body>
</Telegram>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="mom:B">
<Options>
<xsl:apply-templates/>
</Options>
</xsl:template>
<xsl:template match="mom:B1">
<Option code="{.}" family="{position() - 1}"/>
</xsl:template>
</xsl:stylesheet>