XSL help needed for dummy

G

Gina_Marano

Hey All,

I am totally dazed and confused. I am new to XML/XSL and was thrown a
toughy.

Don't shoot me for the xml, it is provided to us and cannot change.
Below is an example of the structure:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="people.xsl"?>
<LIST>
<STATE>
<WA>
<PERSON>
<NAME>Mark Wilson</NAME>
</PERSON>
<PERSON>
<NAME>Tracey Wilson</NAME>
</PERSON>
<PERSON>
<NAME>Jodie Foster</NAME>
</PERSON>
</WA>
<ID>
<PERSON>
<NAME>Lorrin Maughan</NAME>
</PERSON>
<PERSON>
<NAME>Steve Rachel</NAME>
</PERSON>
</ID>
</STATE>
<ADDRESSLIST>
<ADDRESSITEM>
<ADDRESSID>1</ADDRESSID>
<ADDRESS>911 Somewhere Circle, Canberra, Australia</ADDRESS>
</ADDRESSITEM>
<ADDRESSITEM>
<ADDRESSID>2</ADDRESSID>
<ADDRESS>121 Zootle Road, Cape Town, South Africa</ADDRESS>
</ADDRESSITEM>
<ADDRESSITEM>
<ADDRESSID>3</ADDRESSID>
<ADDRESS>30 Animal Road, New York, USA</ADDRESS>
</ADDRESSITEM>
<ADDRESSITEM>
<ADDRESSID>4</ADDRESSID>
<ADDRESS>1143 Winners Lane, London, UK</ADDRESS>
</ADDRESSITEM>
<ADDRESSITEM>
<ADDRESSID>5</ADDRESSID>
<ADDRESS>90210 Beverly Hills, California, USA</ADDRESS>
</ADDRESSITEM>
</ADDRESSLIST>
</LIST>

I need to have it look like this:

<LIST>
<STATE>
<WA>
<PERSON>
<NAME>Mark Wilson</NAME>
<ADDRESS>911 Somewhere Circle, Canberra, Australia</ADDRESS>
</PERSON>
<PERSON>
<NAME>Tracey Wilson</NAME>
<ADDRESS>121 Zootle Road, Cape Town, South Africa</ADDRESS>
</PERSON>
<PERSON>
<NAME>Jodie Foster</NAME>
<ADDRESS>30 Animal Road, New York, USA</ADDRESS>
</PERSON>
</WA>
....

basically associate the address with the person. (note that the list
of items in each state can be a different count)

Any help would be much apprecated!!!!!!!

Frazzled Gina_M
 
G

Gina_Marano

Many, many thanks Roy!

Gina_Marano said:
Don't shoot me for the xml, it is provided to us and
cannot change. Below is an example of the structure:
[...]

I need to have it look like this:
[...]

basically associate the address with the person. (note
that the list of items in each state can be a different
count)

This is a fairly typical entry-level problem. Identity with
exclusion is a good starting point for tasks like this.
Slightly over-engineered solution follows:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="address"
match="/LIST/ADDRESSLIST/ADDRESSITEM/ADDRESS"
use="../ADDRESSID"/>

<xsl:template name="calc-num">
<xsl:value-of
select=
"
count
(
.|
preceding::*
[
name()=name(current()) and
namespace-uri()=namespace-uri(current())
]
)
"/>
</xsl:template>

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

<xsl:template match="PERSON">
<xsl:variable name="num">
<xsl:call-template name="calc-num"/>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="key('address',$num)"/>
</xsl:copy>
</xsl:template>

<xsl:template match="ADDRESSLIST"/>
</xsl:stylesheet>

Key points are aforementioned identity+exclusion (google if
in doubt), calculation of person's position in a document
and injection of the desired sub-tree from elsewhere into
the resulting tree.

--
roy axenov

If only we smelled each other's asses, there wouldn't be any
war.--Dustin Hoffman
 
R

roy axenov

Gina_Marano said:
Don't shoot me for the xml, it is provided to us and
cannot change. Below is an example of the structure:
[...]

I need to have it look like this:
[...]

basically associate the address with the person. (note
that the list of items in each state can be a different
count)

This is a fairly typical entry-level problem. Identity with
exclusion is a good starting point for tasks like this.
Slightly over-engineered solution follows:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="address"
match="/LIST/ADDRESSLIST/ADDRESSITEM/ADDRESS"
use="../ADDRESSID"/>

<xsl:template name="calc-num">
<xsl:value-of
select=
"
count
(
.|
preceding::*
[
name()=name(current()) and
namespace-uri()=namespace-uri(current())
]
)
"/>
</xsl:template>

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

<xsl:template match="PERSON">
<xsl:variable name="num">
<xsl:call-template name="calc-num"/>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="key('address',$num)"/>
</xsl:copy>
</xsl:template>

<xsl:template match="ADDRESSLIST"/>
</xsl:stylesheet>

Key points are aforementioned identity+exclusion (google if
in doubt), calculation of person's position in a document
and injection of the desired sub-tree from elsewhere into
the resulting tree.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top