Subject: RE: [xsl] XSLT Filtering based on defined XML From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Wed, 17 Aug 2005 00:37:11 +0100 |
OK, I' having to make a few guesses about what you want to happen to text nodes etc, but it seems to be something like this: Each node N of the input document has a corresponding node F in the filter document. The root node of the of the input document corresponds to the root node of the filter document. If F has no element children, then N is deep-copied unchanged to the result tree. If F has one or more element children, then N is shallow-copied to the result tree. Those children of N where a child of F exists with the same name are handled recursively using the same rules, using that element of F as the corresponding node; those children of N where no child of F exists with the same name are omitted from the output. OK? (There doesn't seem to be any mechanism for shallow-copying N without any of its children: the rule "no children in the filter means copy all children from the input" seems a slighly odd one). This suggests processing something like this (2.0 solution): <xsl:variable name="in" select="/"/> <xsl:variable name="filter" select="doc('filter.xml')"> <xsl:template match="/"> <xsl:apply-templates select="*"> <xsl:with-param name="f" select="$filter/*"/> </xsl:apply-templates> </xsl:template> <xsl:template match="*"> <xsl:param name="f"/> <xsl:choose> <xsl:when test="$f/*"> <xsl:for-each select="*[node-name() = $f/*/node-name()]"> <xsl:apply-templates select="."> <xsl:with-param name="f" select="f/*[node-name() = current()/node-name()]"/> </xsl:apply-templates> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> Untested, of course. Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Jacquo Johnson [mailto:genxgeek@xxxxxxxxx] > Sent: 17 August 2005 00:09 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: Re: [xsl] XSLT Filtering based on defined XML > > Actually, the nice thing about the requirements in this case is that > the source document will always be the same structure. That is, it is > well defined other than the filters, which can change but only > according to the xml source document definition (just the xml > structure...not refering to a dtd here);: > > Let's say the the following is the actual xml source contents > (always static): > > <Root> > <Node1/> > <Node2> > <Node21/> > <Node22/> > </Node2> > </Root> > > Now the only available filters for this document would be: > > Filter 1: > <Root> > <Node1/> > </Root> > > Output (from Filter1): > <Root> > <Node1/> > </Root> > -- > Filter 2: > <Root> > <Node2> > <Node21/> > </Node2> > </Root> > > Output (from Filter2): > <Root> > <Node2> > <Node21/> > </Node2> > </Root> > > Filter 3: > <Root> > <Node2> > <Node22/> > </Node2> > </Root> > > Output (from Filter3): > <Root> > <Node2> > <Node22/> > </Node2> > </Root> > > Filter 4: > <Root> > <Node2/> > </Root> > > Output (from Filter2): > <Root> > <Node2> > <Node21/> > <Node22/> > </Node2> > </Root> > > Now, since I have a DOM object available I can dynamically create my > own xslt by recursing the filter and create <apply-templates > match="<CurrentNodeFromFilter>"/> and either <copy> if the node > doesn't have children or do a <copy-of> if the node has children. > Once I have the dynamic transform (as created per the filter) I can > call a transform with it on the xml source document to get me the > desired output. This works but I think that it's kludgey. > > ---- > On 8/16/05, Michael Kay <mike@xxxxxxxxxxxx> wrote: > > Your first challenge is to specify this more precisely. > > > > In early drafts of the XQuery specification there was a > function called > > filter() which was a bit like this, but it got taken out > because no-one was > > able to write a precise specification of what it was supposed to do. > > Sketching out an example isn't good enough. Start by > producing a dozen > > examples: For example, what output do you want if one of > the documents is > > > > <a><b/></a> > > > > and the other is > > > > <b><c/></b> > > > > then generalize from the examples to define the actual rules. > > > > Michael Kay > > > > > -----Original Message----- > > > From: Jacquo Johnson [mailto:genxgeek@xxxxxxxxx] > > > Sent: 16 August 2005 20:26 > > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > > > Subject: [xsl] XSLT Filtering based on defined XML > > > > > > Hi All, > > > > > > Is there an elegant pattern via xslt to filter out an > existing source > > > xml document based on the contents of another filter xml document? > > > For example: > > > > > > Source xml doc: > > > <Root> > > > <Node1> > > > <Node11> > > > <Node111/> > > > </Node11> > > > <Node12/> > > > <Node2> > > > ... > > > > > > Filter xml doc: > > > <Root> > > > <Node1> > > > <Node111/> > > > </Node1> > > > </Root> > > > > > > Desired results: > > > <Root> > > > <Node1> > > > <Node111/> > > > </Node1> > > > </Root> > > > > > > Now the issue that I'm dealing with is that the filter xml doc is > > > dynamic. That is, it can be different for any given xml > source doc > > > configuration based on what another server source > specifies. I could > > > recursively build some dynamic xslt and add > apply-templates for each > > > node and make use of copy and copy-of based on if a node > has children > > > or not and then run that dynamically build transform on > the xml doc > > > source...however, can anybody think of another way to do this? > > > > > > Thanks in advance!
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XSLT Filtering based on d, Jacquo Johnson | Thread | Re: [xsl] XSLT Filtering based on d, Jacquo Johnson |
Re: [xsl] XSLT Filtering based on d, Jacquo Johnson | Date | Re: [xsl] XSLT Filtering based on d, Jacquo Johnson |
Month |