Re: flex/bison based xpath parser

Subject: Re: flex/bison based xpath parser
From: Francis Norton <francis@xxxxxxxxxxx>
Date: Mon, 06 Sep 1999 20:21:54 +0100
Hi Sean, everyone - sorry about mis-posting to the list :)

zun@xxxxxxxxxxxxxx wrote:
> 
> Hi Francis, everyone,
> 
> On Fri, 3 Sep 1999, Francis Norton wrote:
> 
> > I've been writing batch files to try to do xpath viewing (which I really
> > need to help analyse large large and rapidly changing XML dump I'm
> > formatting) but getting stymied by XSLT's refusal to permit
> > paramterisation of select attributes - I even tried external entities!
> 
> Have you tried using a stylesheet to generate stylesheets?  Failing that,
> another mechanism would work (under Unix, shell substitution for example).
> 

I've got about 25k of stylesheets-generating-stylesheets in a work
directory right now - I've been *attempting* to implement an XML Schema
structure validator in XSLT and am just psyching myself up for a final
re-write in order to implement the "all" combinator with all sub-models
- and I was just *hoping* to do an xpath evaluator in a slightly more
elegant way...

Anyway, here's the two-phase xpath evaluator for anyone who wants it...



// _xpath.xsl: this one gets an expression merged into it the hard way
//
<qxsl:stylesheet indent-result="yes" default-space="strip" 
	xmlns:qxsl="http://www.w3.org/XSL/Transform/1.0";>

<qxsl:template match="/">
	<targets>
		<qxsl:apply-templates mode="target" />
	</targets>
</qxsl:template>

<qxsl:template match="*" mode="target">
	<qxsl:element name="{name()}">
		<qxsl:attribute name="path">
			<qxsl:apply-templates select="." mode="back" />
		</qxsl:attribute>
		<text>
			<qxsl:value-of select="text()" />
		</text>
		<elements>
			<qxsl:for-each select="*">
				<qxsl:element name="{name()}">
					<qxsl:value-of select="text()" />
				</qxsl:element>
			</qxsl:for-each>
		</elements>
	</qxsl:element>
</qxsl:template>

<qxsl:template match="*" mode="back">
	<qxsl:if test="not(.='/')"><qxsl:apply-templates select=".."
mode="back" />/</qxsl:if><qxsl:value-of select="name()" />
</qxsl:template>
	
</qxsl:stylesheet>



// xpathgen.xsl: this does the merging
//
<xsl:stylesheet
	xmlns:xsl="http://www.w3.org/XSL/Transform/1.0";
	xmlns:qxsl="quote:http://www.w3.org/XSL/Transform/1.0";>

	
	<xsl:param name="xpath" />

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

	<xsl:template match="xsl:apply-templates[@mode='target']">
		<xsl:copy select=".">
			<xsl:attribute name="select"><xsl:value-of select="$xpath"
/></xsl:attribute>
			<xsl:attribute name="mode">target</xsl:attribute>
			<xsl:apply-templates/>
		</xsl:copy>
	</xsl:template>

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



// xpath.bat: this runs it all neatly in a DOS box, ist param is
filename, 2nd is xpath expression
//
@echo off
xt _xpath.xsl xpathgen.xsl xpath=%2>_temp.xsl
xt %1 _temp.xsl



// try it, using XT's top level parameters, and the default file
association for XSL
//
xpath t_.xml //ITEM > x.xml & x.xml


// ... at which point IE5 displays something like this...
//
- <targets>
- <ITEM path="/LIST/ITEM">
  	<text /> 
	- <elements>
		  <DESCR>aaaaa</DESCR> 
		  <NUM>1001</NUM> 
	  </elements>
  </ITEM>
- <ITEM path="/LIST/ITEM">
	  <text /> 
	- <elements>
		  <DESCR>aaaaa</DESCR> 
		  <NUM>1002</NUM> 
	  </elements>
  </ITEM>
  </targets>


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


Current Thread