Ok, I've seen numerous variations on this question, but none exactly answer what I'm trying to solve and perhaps I'm just too dense to see how to apply one of the other answers to what I'm trying to do.
I have some XML that looks something like the following:
<?xml version="1.0" encoding="utf-8"?>
<message>
<cmd id="api_info">
<api-version>1.0</api-version>
<api-build>1.0.0.0</api-build>
</cmd>
</message>
Now I have an XSLT transform that I'm applying to this XML. The XSLT is similar to the following:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
version="2.0">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="message"/>
</xsl:template>
<xsl:template match="message">
<xsl:element name="message" xmlns="http://www.companyname.com/schemas/product/Version001">
<xsl:apply-templates select="/message/cmd/@id"/>
</xsl:element>
</xsl:template>
<xsl:template match="/message/cmd/@id">
<xsl:variable name="_commandType" select="/message/cmd/@id"/>
<xsl:element name="messageHeader">
<xsl:element name="cmdType">
<xsl:value-of select="$_commandType"/>
</xsl:element>
</xsl:element>
<xsl:element name="messageBody">
<xsl:choose>
<xsl:when test="$_commandType = 'api_info'">
<xsl:element name="apiInfoBody">
<xsl:element name="apiVersion">
<xsl:value-of select="/message/cmd/api-version"/>
</xsl:element>
<xsl:element name="apiBuild">
<xsl:value-of select="/message/cmd/api-build"/>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:when test="$_commandType = 'communicationError'">
<xsl:element name="communicationErrorBody">
<xsl:element name="errorCode">
<xsl:value-of select="error-code"/>
</xsl:element>
<xsl:element name="badCmd">
<xsl:value-of select="bad-cmd"/>
</xsl:element>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The output I get is basically what I want and looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<message xmlns="http://www.companyname.com/schemas/product/Version001">
<messageHeader xmlns="">
<cmdType>api_info</cmdType>
</messageHeader>
<messageBody xmlns="">
<apiInfoBody>
<apiVersion>1.0</apiVersion>
<apiBuild>1.0.0.0</apiBuild>
</apiInfoBody>
</messageBody>
</message>
But what I don't want are the xmlns="" attributes in the <messageHeader> and <messageBody> elements.
Now I've found that if I explicitly specify the namespace in the XSLT for those elements, then the unwanted attribute gets pushed down one level to the children of those attributes.
I could just go through my entire XSLT and explicitly add the xmlns=""http://www.companyname.com/schemas/product/Version001" attribute to each of my xsl:element definitions, but I know that there must be a more elegant way. We programmers are far too lazy to not have a shortcut for this kind of nonsense. If my XSLT didn't consist of something as simple as the shortened example, I be tempted to do it that way. But I know there must be a better way.
Does anyone know what I'm missing here?
Thanks,
AlarmTripper
The standard way to transform XML data into other formats is by Extensible Stylesheet Language Transformations (XSLT). You can use the built-in XSLTRANSFORM function to convert XML documents into HTML, plain text, or different XML schemas. XSLT uses stylesheets to convert XML into other data formats.
If you code disable-output-escaping="yes" , the character > is written instead. The XSLT processor uses this attribute only if you use the html or xml output methods. If you use <xsl:output method="test"> , the attribute is ignored becasue output escaping is not done for the text output method.
In XML a namespace is a collection of names used for elements and attributes. A URI (usually, a URL) is used to identify a particular collection of names.
The exclude-result-prefixes attribute in both XSLT 1.0 and XSLT 2.0 allows for the exclusion of certain namespace declarations in the output document.
Use exclude-result-prefixes on the xsl:stylesheet tag with the prefix "#default"
The reference in w3c for this is HERE
EDIT: OK, I should have studied your XSL more carefully. Move the xmlns on the message tag up to the stylesheet tag. This will put ALL the result elements in the same namespace and result in one namespace attribute on the message tag. I ran this in Oxygen/XML and got the output you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With