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

Re: [xsl] Filtering XML elements based on tokenized external parameters?


Subject: Re: [xsl] Filtering XML elements based on tokenized external parameters?
From: "Sam D. Chuparkoff" <sdc@xxxxxxxxxx>
Date: Fri, 17 Jun 2005 11:23:40 -0700

I just joined this list so I thought I'd post something. I don't know
exactly what you're looking for in (2), but this is (1). I say if you
want to add the nodes that are connected to nodes you are keeping, just
tinker with the matches.

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="nodelist"/>
  <xsl:variable name="nodeids" select="concat(' ',$nodelist,' ')"/>

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

  <xsl:template match="node[$nodelist and
                       not(contains($nodeids, concat(' ',@id,' ')))]"/>
  
  <xsl:template match="edge[$nodelist and
                       not(contains($nodeids,concat(' ',@to,' ')) and
                       contains($nodeids,concat(' ',@from,' ')))]"/>
</xsl:stylesheet>

This would look a little neater in 2.0, but I don't know a better way
for libxslt.

You'd run this like:

xsltproc --stringparam nodelist "alpha beta" foo.xsl foo.xml

Have fun.

sdc

On Fri, 2005-06-17 at 09:44 -0700, Ramon Felciano wrote:
> Hello --
> 
> I'm trying to do parameterized XSLT-based filtering to strip out
> unwanted structure from an XML file. The XML file represents a graph
> data structure along with some other metadata. Conceptually I want to
> extract a subgraph from this data structure, but want to do so in an
> upwards-compatible way such that any additional tags in the XML are
> carried over to the resulting document. For example, given this XML
> file:
> 
> <graph>
>     <node id="alpha"/>
>     <node id="beta"/>
>     <node id="delta"/>
>     <node id="gamma"/>
>     <edge from="alpha" to="delta"/>
>     <edge from="alpha" to="beta"/>
>     <edge from="alpha" to="gamma"/>
>     <edge from="beta" to="beta"/>
>     <mymetadata id="123"/>
> </graph>
> 
> Given the above simple graph data structure, I want to produce a
> filtered version that only includes node elements (ideally both node and
> edge elements) that match a given set of input parameters, as well as
> any other tags that might be included (e.g. the mymetadata tag). I'd
> ideally like to issue a call like this so that I integrate this w shell
> scripts:
> 
>     xsltproc mytransform.xslt myfile.xml --param nodelist "alpha,beta"
> 
> And get this back:
> 
> <graph>
>     <node id="alpha"/>
>     <node id="beta"/>
>     <edge from="alpha" to="beta"/>
>     <edge from="beta" to="beta"/>
>     <mymetadata id="123"/>
> </graph>
> 
> I have two questions:
> 
> 1. What is the best way to create a pattern match that is parameterized
> based on the incoming nodelist? I'd like to flexible about delimeters
> (e.g. have both "alpha,beta" and "alpha   ,   beta" work). I've tried
> playing with tokenize from EXSLT but can't figure how to use the
> resulting tokens to implement the filtering in a single-pass.
> 
> 2. Is there a way to implement this to also include the alpha-gamma edge
> and the gamma node, based on the partial edge match to "alpha"? I know
> how to do this w multiple passes (e.g. by marking the edges, then the
> nodes, then filtering) but was wondering if there was a nice one-pass
> functional approach I've missed.
> 
> Thank you in advance for your time.
> 
> Ramon
> 
> _________________________________
> 
> Ramon M. Felciano
> INGENUITY Systems, Inc.


Current Thread
Keywords
xml