xsl-list
[Top] [All Lists]

Re: Custom node-set in a variable

2005-02-17 09:48:29
Leonid,

At 09:42 AM 2/17/2005, you wrote:
Now I need to exclude certain xml elements from the transformations by
name.
The list of such elements is long.
Can I use a variable inside my XSL as a custom node-set, something like:
   <xsl:variable name="bypass-names">
      <element1 />
      <element2 />
...
   </xsl:variable>

You can do this, but it requires a little extra effort to do so in XSLT 1.0. This is because a variable declared this way is not bound to a true node-set, but rather to a result tree fragment -- which is much like a node set with the caveat that you can't query into it -- which is, unfortunately, exactly what you need to do.

The XSLT 1.0 workaround to this problem takes two forms:

* use an extension function such as exslt:node-set() to turn the result fragment into a node set * use the document() function to query the document where this node set appears, instead of simply using the variable as bound. Since document('') returns the stylesheet as a (parsed) document, this can be done like so:

   <xsl:variable name="bypass-names-RTF">
      <element1 />
      <element2 />
...
   </xsl:variable>

   <xsl:variable name="bypass-names"
   select="document('')/*/xsl:variable[(_at_)name='bypass-names-RTF]/*"/>

So now $bypass-names is actually a node set, which you can traverse.

Now as for your real question....

And what would be the good way to handle the exclusion, keeping in mind
performance?

Actually, not as you have it, like

<xsl:variable name="bypass-names-RTF">
   <element1 />
   <element2 />
   ...
</xsl:variable>

but rather something like

<xsl:variable name="bypass-names-RTF">
   <name>element1</name>
   <name>element2</name>
   <name>element3</name>
   ...
</xsl:variable>

This is nice because then the names you want to bypass can be collected as a set of nodes whose values, not names, can be checked against. That is, since $bypass-names (using the declaration described above) will be a set of <name> elements, the names you want to exclude is available as the *values* of the node-set $bypass-names.

The equality operator "=" in XPath is very handy for the test you then need to do ... for any element in your input, when

test="name() = $bypass-names"

you know its name is in the set.

(You might want to research the name() and local-name() functions, since it could matter which one you use, if you have namespaces in play.)

This is a special application of a "lookup table", which you will find documented in the XSLT FAQ and elsewhere.

Cheers,
Wendell


======================================================================
Wendell Piez                            
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


--~------------------------------------------------------------------
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>