Randmness
Randmness

Reputation: 27

XSLT for XML containing multiple namespaces

I'm working on an XSLT that is giving me a little headache, and was looking for some tips. I'm working on converting an XML where some of the tags have namespaces prefixes, and others do not. I am working to convert all of the tags to one common namespace prefix.

Example of XML:

<yes:Books>
   <no:Book>
      <Title>Yes</Title>
      <maybe:Version>1</maybe:Version>
   </no:Book>
</yes:Books>

What I'm trying to get:

<yes:Books>
   <yes:Book>
      <yes:Title>Yes</yes:Title>
      <yes:Version>1</yes:Version>
   </yes:Book>
</yes:Books>

The XML input is the aggregate of several webservices, that are returning various namespaces. I have no issue aggregating it together appropriately, it's creating one common prefix namespace that I am having an issue with.

Worst case, I could regex them away, but I'm sure that isn't recomended.

Thanks.

Upvotes: 2

Views: 376

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243549

This transformation allows the wanted final prefix and its namespace to be specified as external/global parameters. It shows how to process in the same way attribute names:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pPrefix" select="'yes'"/>
 <xsl:param name="pNamespace" select="'yes'"/>

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

 <xsl:template match="@*">
  <xsl:attribute name="{$pPrefix}:{local-name()}" namespace="{$pNamespace}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

when applied on the following document (the provided one with one added attribute to make the problem more challenging):

<yes:Books xmlns:yes="yes">
    <no:Book xmlns:no="no">
        <Title no:Major="true">Yes</Title>
        <maybe:Version xmlns:maybe="maybe">1</maybe:Version>
    </no:Book>
</yes:Books>

produces the wanted, correct result:

<yes:Books xmlns:yes="yes">
   <yes:Book>
      <yes:Title yes:Major="true">Yes</yes:Title>
      <yes:Version>1</yes:Version>
   </yes:Book>
</yes:Books>

Upvotes: 2

alanstroop
alanstroop

Reputation: 156

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="c">
    <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="custom:{local-name()}" namespace-uri="c">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Related Questions