Re: [xsl] Moving an element to a different grouping based on a child value: use xsl:copy-of?

Subject: Re: [xsl] Moving an element to a different grouping based on a child value: use xsl:copy-of?
From: Rob Newman <rlnewman@xxxxxxxx>
Date: Wed, 21 Jan 2009 16:29:53 -0800
Thank you very much Mukul - this worked nicely.

Best regards,
- Rob

On Jan 16, 2009, at 6:36 PM, Mukul Gandhi wrote:

Hi Rob,
 This seems to work,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                      version="2.0">

<xsl:output method="xml" indent="yes" />

<xsl:template match="/">
<kml xmlns="http://earth.google.com/kml/2.1";>
<Document>
<xsl:for-each select="station_list/snets/snet">
<xsl:variable name="idval" select="@id" />
<Folder id="{$idval}">
<name><xsl:value-of select="." /></name>
<xsl:for-each select="../../stations/station[Network = $idval]">
<Placemark>
<name><xsl:value-of select="@name" /></name>
</Placemark>
</xsl:for-each>
</Folder>
</xsl:for-each>
</Document>
</kml>
</xsl:template>


</xsl:stylesheet>

I think xsl:copy-of will not be required. A simple for-each iteration
would work.

On Sat, Jan 17, 2009 at 4:25 AM, Rob Newman <rlnewman@xxxxxxxx> wrote:
Dear XSL gurus,

I have some XML in the following format:

INPUT XML
---------------
<station_list>
      <snets>
              <snet id="AZ">AZ (UC San Diego)</snet>
              <snet id="BK">BK (UC Berkeley)</snet>
              <snet id="CI">CI (CalTech)</snet>
              <snet id="IU">IU GSN</snet>
              <snet id="NN">NN (UN Reno)</snet>
              <snet id="TA">TA (USArray)</snet>
              <snet id="US">US ANSS</snet>
              <snet id="UU">UUSS (Uni. Utah)</snet>
      </snets>
      <stations>
              <station name="MONP">
                      <Network>AZ</Network>
              </station>
              <station name="BDM">
                      <Network>BK</Network>
              </station>
              <station name="FARB">
                      <Network>BK</Network>
              </station>
              <station name="109C">
                      <Network>TA</Network>
              </station>
              <station name="A05A">
                      <Network>TA</Network>
              </station>
              <station name="Z14A">
                      <Network>TA</Network>
              </station>
              <station name="US">
                      <Network>MSTX</Network>
              </station>

..... [lots of <station> elements, over 600]....

      </stations>
</station_list>

I want to group the output on the <snet> element id attribute value, moving
all matching <Network> stations into their respective <snet> group. Like the
following format:


DESIRED OUTPUT XML
-----------------------------
<kml xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns="http://earth.google.com/kml/2.1";>

<Document>

              <Folder id="AZ">
                      <name>AZ (UC San Diego)</name>
                      <Placemark>
                              <name>MONP</name>
                      </Placemark>
              </Folder>

              <Folder id="BK">
                      <name>BK (UC Berkeley)</name>
                      <Placemark>
                              <name>BDM</name>
                      </Placemark>
                      <Placemark>
                              <name>FARB</name>
                      </Placemark>
              </Folder>

              <Folder id="TA">
                      <name>TA (USArray)</name>
                      <Placemark>
                              <name>109C</name>
                      </Placemark>
              </Folder>

              <Folder id="US">
                      <name>ANSS</name>
                      <Placemark>
                              <name>MSTX</name>
                      </Placemark>
              </Folder>

</Document>

</kml>

Essentially I want to iterate through the document tree looking for each
<station> <Network> element, then relocating it into the different groups of
<snet>. The following XSLT works for generating the <Folder> elements, but
how do I match the <Network> element value and move them to the correct
<Folder> groups? I have read about <xsl:copy> and <xsl:copy-of>, but can't
seem to figure out how to write an expression that will work.


XSL
----
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
      xmlns="http://earth.google.com/kml/2.1";
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
      xmlns:xs="http://www.w3.org/2001/XMLSchema";>

      <xsl:output method="xml" indent="yes"
cdata-section-elements="description" />

      <xsl:template match="/">
      <kml>
              <Document>
                      <xsl:for-each select="station_list/snets/snet">
                              <Folder id="{@id}">
                                      <name><xsl:value-of select="."
/></name>
                              </Folder>

                              <!-- Some sort of xsl:copy-of select
expression to get the matching <station> <Network> values? -->
                              <!-- Guessing here -->

                              <xsl:apply-templates
select="station_list/stations/station/" />

                      </xsl:for-each>
              </Document>
      </kml>
      </xsl:template>

      <xsl:template match="station_list/stations/station/">
      <Placemark>
              <name><xsl:value-of select="@name" /></name>
      </Placemark>
      </xsl:template>

</xsl:stylesheet>


Any help appreciated! I hope I have explained this clearly. I know this is
probably a newbie question, so please bear with me - I only occasionally
dabble in XSL.


Thanks in advance,
- Rob



-- Regards, Mukul Gandhi

Current Thread