xsl-list
[Top] [All Lists]

RE: XSLT Filtering based on defined XML

2005-08-16 16:37:11
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(_at_)gmail(_dot_)com] 
Sent: 17 August 2005 00:09
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_at_)saxonica(_dot_)com> 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(_at_)gmail(_dot_)com]
Sent: 16 August 2005 20:26
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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!


--~------------------------------------------------------------------
XSL-List info and archive:  
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--






--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>