[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Using XPath to match two node levels with the same name


Subject: [xsl] Using XPath to match two node levels with the same name
From: "Mark Peters" <flickrmeister@xxxxxxxxx>
Date: Mon, 7 Aug 2006 08:52:30 -0400

Hi guys,

I'm trying to split a set of nested <topic> elements into separate XML
files using the Xalan redirect extension. My input XML document could
contain as many as four levels of <topic> elements, with <topic> being
the root-level node. My plan is to split the root-level <topic> into
its own file (without including any child <topic>s). The first level
of child <topic>s would also get their own files. This set of files
would include any nested <topic> elements.

My plan is to split a chapter of technical documentation containing
nested topics into a separate files containing the chapter-level
(overview) topic file and the major heading topics.

Can I match the two desired levels of <topic> elements using XPath?
I'm guessing I could use match="root" to express the top
(chapter-level) node. But I'm having some trouble wrapping my mind
around the XPath processing flow ("contains"?  "ancestor"?
"following-sibling"?) to formulate a match for my highest child
<topic> elements.


This is my input XML:


<topic id="1">
	<title>Root level</title>
	<prolog/>
	<body>
		<p>This is the root-level topic.</p>
	</body>
	<topic id="2a">
		<title>Child level 2a</title>
		<prolog/>
		<body>
			<p>This is child level 2a.</p>
		</body>
		<topic id="3a">
			<title>Child level 3a</title>
			<prolog/>
			<body>
				<p>This is child level 3a.</p>
			</body>
		</topic>
	</topic>
	<topic id="2b">
		<title>Child level 2b</title>
		<prolog/>
		<body>
			<p>This is child level 2b.</p>
		</body>
		<topic id="3b">
			<title>Child level 3b</title>
			<prolog/>
			<body>
				<p>This is child level 3b.</p>
			</body>
		</topic>
		<topic id="3c">
			<title>Child level 3c</title>
			<prolog/>
			<body>
				<p>This is child level 3c.</p>
			</body>
		</topic>
	</topic>
</topic>


This is my desired output XML (3 separate XML files):



File 1:


<topic id="1">
	<title>Root level</title>
	<prolog/>
	<body>
		<p>This is the root-level topic.</p>
	</body>
</topic>


File 2:


<topic id="2a">
	<title>Child level 2a</title>
	<prolog/>
	<body>
		<p>This is child level 2a.</p>
	</body>
	<topic id="3a">
		<title>Child level 3a</title>
		<prolog/>
		<body>
			<p>This is child level 3a.</p>
		</body>
	</topic>
</topic>


File 3:


<topic id="2b">
	<title>Child level 2b</title>
	<prolog/>
	<body>
		<p>This is child level 2b.</p>
	</body>
	<topic id="3b">
		<title>Child level 3b</title>
		<prolog/>
		<body>
			<p>This is child level 3b.</p>
		</body>
	</topic>
	<topic id="3c">
		<title>Child level 3c</title>
		<prolog/>
		<body>
			<p>This is child level 3c.</p>
		</body>
	</topic>
</topic>


This is my XSL stylesheet draft:


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:redirect="http://xml.apache.org/xalan/redirect"
extension-element-prefixes="redirect" version="1.0">
	<xsl:output method="xml"/>

	<xsl:template match="/">
		<xsl:apply-templates/>
	</xsl:template>

	<xsl:template match="root">
		<xsl:variable name="filename" select="concat(@id,'.xml')"/>
		<redirect:write select="$filename">
			<topic id="{@id}">
				<xsl:apply-templates/>
			</topic>
		</redirect:write>
	</xsl:template>

	<xsl:template match="topic[???]">
		<xsl:variable name="filename" select="concat(@id,'.xml')"/>
		<redirect:write select="$filename">
			<topic id="{@id}">
				<xsl:apply-templates/>
			</topic>
		</redirect:write>
	</xsl:template>
	<xsl:template match="title">
		<xsl:copy-of select="."/>
	</xsl:template>
	<xsl:template match="prolog">
		<xsl:copy-of select="."/>
	</xsl:template>
	<xsl:template match="body">
		<xsl:copy-of select="."/>
	</xsl:template>
</xsl:stylesheet>


Any help would be greatly appreciated.


Regards,
Mark


--


Mark Peters
Senior Technical Writer
Saba Software


Current Thread
Keywords