tags:

views:

46

answers:

2

How do I encapsulate nodes around my XML blocks using XSLT? For example, I have the following XML file.

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <Root>
      <VOBaseCollection>
        <xsl:apply-templates select="Root/Location" />
      </VOBaseCollection>
    </Root>
  </xsl:template>
  <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

My input XML file looks like this.

  <Root>
<Location><Name>Pennsylvania</Name><Type>State</Type></Location>
</Root>

I wish the output to look like this.

      <Root><Container>
    <Location><Name>Pennsylvania</Name><Type>State</Type></Location>
</Container>
    </Root>

I wish to make sure that a node called <CONTAINER> gets applied every time, it copies over information from Root/Location. What changes do I need to do to my XSLT file?

A: 

I am just guessing, and in guess mode it seems that you want this:

EDIT: helped by another guess by Mads Hansen...

Add this to the identity template you already have:

<xsl:template match="Location">
  <CONTAINER><xsl:apply-templates/></CONTAINER>
</xsl:template>
Dimitre Novatchev
There is no CONTAINER in my XML document, so where will it do the matching?
abhi
@abhi: You haven't shown any XML document and *this* is the real problem... When you say: "I wish to make sure that a node called `<CONTAINER>` gets applied every time" -- I understand that there is a `<CONTAINER>` in the XML document and you wish that every time it is matched (a template is applied to it), then a certain processing (copying of `Root/Location`) must be done.Please, edit your question and define it better. Also, provide a minimal XML document!
Dimitre Novatchev
@Dimitre - He wants to match on `Location` and wrap with `Container`: `<xsl:template match="Location"> <Container> <xsl:call-template name="identity" /> </Container> </xsl:template>`
Mads Hansen
@abhi: Probably the latest edit in my answer finally produces your desired result?
Dimitre Novatchev
@Dimitre, Your latest solution gives me the container tag wrapped around the xml, but gets rid of the child nodes. In this case my output changes to<CONTAINER>PennsylvniaState</CONTAINER>
abhi
@abhi: This means that you don't have the identity template. It is in your code, I just provided the one additional template you must have.
Dimitre Novatchev
That's correct. The only template I have is the one you see in my original question.
abhi
@abhi: In your question there are *two* templates. The identity template is this one (as copied from your question and now pasted):` <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> `
Dimitre Novatchev
A: 

Summarizing all the answers in comments, this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Location">
        <Container>
            <xsl:call-template name="identity"/>
        </Container>
    </xsl:template>
</xsl:stylesheet>

Result:

<Root>
    <Container>
        <Location>
            <Name>Pennsylvania</Name>
            <Type>State</Type>
        </Location>
    </Container>
</Root>
Alejandro
This has partially resolved the issue. Thanks. Alejandro.
abhi