[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] XSLT Filtering based on defined XML
Subject: Re: [xsl] XSLT Filtering based on defined XML From: Jacquo Johnson <genxgeek@xxxxxxxxx> Date: Tue, 16 Aug 2005 17:51:37 -0600 |
Yes, Indeed! Thank you very much for the help with this one, Michael! On 8/16/05, Michael Kay <mike@xxxxxxxxxxxx> wrote: > 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, Michael Kay | Thread | [xsl] Perl XSLT Module based on SAX, Jacquo Johnson |
RE: [xsl] XSLT Filtering based on d, Michael Kay | Date | [xsl] Converting <xml> StyleSheet p, Jacquo Johnson |
Month |