XML Tutorials

  Home arrow XML Tutorials arrow Page 3 - Querying XML
XML TUTORIALS

Querying XML
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2008-01-17

    Table of Contents:
  • Querying XML
  • 9.1 Performing Set Operations on Node Sets
  • Performing Set Operations on Node Sets continued
  • 9.2 Performing Set Operations on Node Sets Using Value Semantics

  •  
     

    SEARCH CODEWALKERS

    TOOLS YOU CAN USE

    advertisement

    Querying XML - Performing Set Operations on Node Sets continued


    (Page 3 of 4 )

    Now, if you were issuing life insurance, you might consider charging each of the following sets of people different rates:

      <!-- Male smokers -->
      <xsl:variable name="super-risk"
           select="$males[count(. | $smokers) = count($smokers)]"/>
      <!-- Female smokers -->
      <xsl:variable name="high-risk"

           select="$females[count(. | $smokers) = count($smokers)]"/>
      <!-- Male non-smokers -->
      <xsl:variable name="moderate-risk"
           select="$males[count(. | $non-smokers) = count($non-smokers)]"/>
     
    <!-- Female non-smokers -->
      <xsl:variable name="low-risk"
           select="$females[count(. | $non-smokers) = count($non-smokers)]"/>

    You probably noticed that the same answers could have been acquired more directly by using logic rather than set theory:

      <!-- Male smokers -->
      <xsl:variable name="super-risk"
           select="//person[@sex='m' and @smoker='y']"/>
      <!-- Female smokers -->
      <xsl:variable name="high-risk"
           select="//person[@sex='f' and @smoker='y']"/>
      <!-- Male non-smokers -->
      <xsl:variable name="moderate-risk"
           select="//person[@sex='m' and @smoker='n']"/>
      <!-- Female non-smokers -->
      <xsl:variable name="low-risk"
           select="//person[@sex='f' and @smoker='n']"/>

    Better still, if you already had the set of males and females extracted, it would be more efficient to say:

      <!-- Male smokers -->
      <xsl:variable name="super-risk"

           select="$males[@smoker='y']"/>
      <!-- Female smokers -->
      <xsl:variable name="high-risk"
           select="$females[@smoker='y']"/>
      <!-- Male non-smokers -->
      <xsl:variable name="moderate-risk"

           select="$males[@smoker='n']"/>
      <!-- Female non-smokers -->
      <xsl:variable name="low-risk"
           select="$females[@smoker='n']"/>

    These observations do not invalidate the utility of the set approach. Notice that the set operations work without knowledge of what the sets themselves contain. Set operations work at a higher level of abstraction. Imagine that you have a complex XML document and are interested in the following four sets:

      <!-- All elements that have elements c1 or c2 as children-->
      <xsl:variable name="set1" select="//*[c1 or c2]"/>
      <!-- All elements that have elements c3 and c4 as children-->
      <xsl:variable name="set2" select="//*[c3 and c4]"/>
      <!-- All elements whose parent has attribute a1-->
      <xsl:variable name="set3" select="//*[../@a1]"/>
      <!-- All elements whose parent has attribute a2-->
      <xsl:variable name="set4" select="//*[../@a2]"/>

    In the original example, it was obvious that the sets of males and females (and smokers and nonsmokers) are disjoint. Here you have no such knowledge. The sets may be completely disjointed, completely overlap, or share only some elements. There are only two ways to find out what is in common between, say,set1andset3. The first is to take their intersection; the second is to traverse the entire document again using the logicalandof their predicates. In this case, the intersection is clearly the way to go.

    EXSLT defines a set module that includes functions performing the set operations discussed here. The EXSLT uses an interesting technique to return the result of its set operations. Instead of returning the result directly, it applies templates to the result in a mode particular to the type of set operation. For example, after EXSLTset:intersectioncomputes the intersection, it invokes<xsl:apply-templates mode="set:intersection"/>on the result. A default template exists in EXSLT with this mode, and it will return a copy of the result as a node-tree fragment. This indirect means of returning the result allows users importing the EXSLT set module to override the default to process it further. This technique is useful but limited. It is useful because it potentially eliminates the need to use the node-set extension function to convert the result back into a node set. It is limited because there can be at most one such overriding template per matching pattern in the user stylesheet for each operation. However, you may want to do very different post-processing tasks with the result of intersections invoked from different places in the same stylesheet.

    Do not be alarmed if you do not grasp the subtleties of EXSLT’s technique discussed here. Chapter 16 will discuss in more detail these and other techniques for making XSLT code reusable.

    See Also

    You can find an explanation of the EXSLT set operations at http://www.exslt.org/set/ index.html.

    More XML Tutorials Articles
    More By O'Reilly Media

    blog comments powered by Disqus

    XML TUTORIALS ARTICLES

    - Validation with Document Type Definitions (D...
    - Creating a Well-Formed XML Document
    - Getting to Know XML
    - A Friendly Approach to XML
    - Creating RSS 2.0 Feeds
    - Using Modules in Your RSS Feed
    - RSS 2.0
    - Querying XML: Use Cases
    - Joins and Query Use with XML
    - Solving Problems by Querying XML
    - Performing Set Operations When Querying XML
    - Querying XML
    - Handling Data for Ajax with JSON
    - Handling XML Data for Ajax
    - XML and JSON for Ajax


    © 2003-2012 by Developer Shed. All rights reserved. DS Cluster 1 - Follow our Sitemap