Question

I want to transform an XML document. The source XML looks like this:

<svc:ElementList>
    <svc:Element>
        <Year>2007</Year>
    </svc:Element>
    <svc:Element>
        <Year>2006</Year>
    </svc:Element>
    <svc:Element>
        <Year>2005</Year>
    </svc:Element>
</svc:ElementList>

I want to turn that into:

<ElementList>
    <NewTag2007/>
    <NewTag2006/>
    <NewTag2005/>
</ElementList>

The following line of code isn't working:

<xsl:element name="{concat('NewTag',Element/Year)}"/>

The output is a series of elements that look like this: < NewTag >. (Without the spaces...)

"//Element/Year", "./Element/Year", and "//svc:Element/Year" don't work either. One complication is that the "Element" tag is in the "svc" namespace while the "Year" tag is in the default namespace.

So anyway, am I facing a namespace issue or am I mis-using the "concat()" function?

Was it helpful?

Solution

Probably namespace issues and maybe one with current context. For source (with added namespace declaration to make it well-formed xml)

<svc:ElementList xmlns:svc="svc">
  <svc:Element>
    <Year>2007</Year>
  </svc:Element>
  <svc:Element>
    <Year>2006</Year>
  </svc:Element>
  <svc:Element>
    <Year>2005</Year>
  </svc:Element>
</svc:ElementList>

the stylesheet

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:svc="svc"
                version="1.0">
  <xsl:template match="svc:ElementList">
    <xsl:element name="{local-name()}">
      <xsl:for-each select="svc:Element">
        <xsl:element name="{concat('NewTag', Year)}"/>
      </xsl:for-each>
    </xsl:element>
  </xsl:template> 
</xsl:stylesheet>

will give you the output you need. Note that svc:Element needs to be selected using namespace prefixed and that the context when generating the new tags is svc:Element, not svc:ElementList.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top