Re: [xsl] Finding wanted nodes in complex document

Subject: Re: [xsl] Finding wanted nodes in complex document
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Fri, 11 Oct 2002 22:31:07 +0200
Hi Geoff,

for such tasks it's better to use <xsl:template/> instead of <xsl:for-each/>. With templates it's easier to walk down the tree to different levels:

<xsl:template match="bookmarks">
  <bookmarks>
    <category>
      <xsl:apply-templates select="DT/H3"/>
      <xsl:apply-templates select="DL[DT/H3]"/>
    </category>
  </bookmarks>
</xsl:template>

<xsl:template match="DL">
  <subcat level="{count(ancestor::DL)}">
    <xsl:apply-templates select="DT/H3"/>
    <xsl:apply-templates select="DL[DT/H3]"/>
  </subcat>
</xsl:template>

<xsl:template match="H3">
  <xsl:attribute name="name">
    <xsl:value-of select="."/>
  </xsl:attribute>
</xsl:template>

I don't think that you get the expected output, but it should give you an idea how templates work.

I explained your error below ...

Geoff wrote:
I have a big,complicate, messy xml document (originally a Mozilla
bookmark file that I made into well-formed xml) that I wish to transform
into a lean, mean and clean xml document and I am having some trouble.


Here is part of the document: <?xml version="1.0" encoding="UTF-8"?> <bookmarks> <DT> <H3 ADD_DATE="1032875519" ID="NC:BookmarksRoot#$f68320c5" LAST_MODIFIED="1033072101">Consumer Guides</H3> </DT> <DL> <p/> <DT> <H3 ADD_DATE="1032876491" ID="NC:BookmarksRoot#$f68320c6">Alabama</H3> </DT> <DL> <p/> </DL> <p/> <DT> <H3 ADD_DATE="1032876720" ID="NC:BookmarksRoot#$f68320dc" LAST_MODIFIED="1033071828">Minnesota</H3> </DT> <DL>

What you are doing wrong? From your category <H3/> elements you always go up to the <DL> element above (first part '../../' of the XPath in <xsl:value-of/>). Now with the rest of the XPath you go down the tree to the first DL/DT/H3. And this is always the <H3>Mediation</H3> element.


Regards,

Joerg

<p/>
<DT>
<H3 ADD_DATE="1033068848" ID="NC:BookmarksRoot#$c0ebfb0"
LAST_MODIFIED="1033077022">Alternative Dispute
Resolution</H3>
</DT>
<DL>
<p/>
<DT>
<H3 ADD_DATE="1032902327"
ID="NC:BookmarksRoot#$f6832141"
LAST_MODIFIED="1033077446">Mediation</H3>
</DT>
<DL>
<p/>
<DT>
<A ADD_DATE="1033077149"
HREF="http://www.co.hennepin.mn.us/courts/ConcCt/ccmediation.htm";
LAST_CHARSET="ISO-8859-1"
LAST_MODIFIED="1033077270">Mediation in
Conciliation Court [From the Hennepin County
District Court]</A>
</DT>
</DL>
<p/>
<DT>
<A ADD_DATE="1033076751"
HREF="http://www.courts.state.mn.us/adr/adr_info.htm";
LAST_CHARSET="ISO-8859-1"
LAST_MODIFIED="1033076778">Minnesota Alternative
Dispute Resolution [From the Judicial
System]</A>
</DT>
<DT>
<A ADD_DATE="1033076913"
HREF="http://www.co.hennepin.mn.us/courts/Arbitration/arbmain.htm";
LAST_CHARSET="ISO-8859-1"
LAST_MODIFIED="1033076983"
LAST_VISIT="1033077513">What You Need to Know
About Arbitration [From the
Hennepin County District Court]</A>
</DT>
</DL>

<shortened/>


OK I told you it was messy.
So first I want to get all the "categories" which I do like this:

<xsl:for-each select="bookmarks/DL/DL/DT/H3">
	<category>
		<xsl:attribute name="name">
			<xsl:value-of select="."/>
		</xsl:attribute>		
	</category>
</xsl:for-each>
This gives me a nice clean document like this:
  <category name="Alternative Dispute Resolution"/>
  <category name="Bankruptcy"/>
  <category name="Business Law"/>
  <category name="Charities"/>
  <category name="Civil Rights Law"/>
  <category name="Courts"/>
  <category name="Consumer Law"/>
  <category name="Contracts"/>
etc....
Now I want to get the "subcategories" related to the "categories" which
are at "bookmarks/DL/DL/DL/DT/H3" or "../../DL/DT/H3" when compared to
the "category" node.

So what I want is something like this:
<category name="Alternative Dispute Resolution">
	<subcat name="Mediation"/>
</category>
<category name="Bankruptcy"/>
<category name="Business Law">
	<subcat name="Corporations"/>
</category>

I am attempting to do this like this:
<xsl:for-each select="bookmarks/DL/DL/DT/H3">
<category>
<xsl:attribute name="name">
<xsl:value-of select="."/>
</xsl:attribute>

<subcat>
<xsl:attribute name="name">
<xsl:value-of select="../../DL/DT/H3"/>
</xsl:attribute>
</subcat>
</category>
</xsl:for-each>
But this produces this:
<category name="Alternative Dispute Resolution">
<subcat name="Mediation"/>
</category>
<category name="Bankruptcy">
<subcat name="Mediation"/>
</category>
<category name="Business Law">
<subcat name="Mediation"/>
</category>
<category name="Charities">
<subcat name="Mediation"/>
</category>


What am I doing wrong??


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Current Thread