You can match a variety of nodes with XPath using name and node tests. A name test can match any element name, any element name with a given prefix, or a QName (a namespace-qualified name, with or without a prefix). Node tests can match text, comment, processing instruction nodes, or any node. You can use abbreviated or unabbreviated syntax with name and node tests. Table 4-4 describes each of the tests.
Example 4-8 shows a RELAX NG schema for provinces.xml called provinces.rng. Example 4-8. A RELAX NG schema for provinces.xml<?xml version="1.0"?> <!--Relax NG schema for provinces.xml--> <rng:element name="provinces" xmlns:rng="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> <rng:oneOrMore> <rng:element name="province"> <rng:attribute name="id"> <rng:data type="ID"/> </rng:attribute> <rng:element name="name"> <rng:text/> </rng:element> <rng:element name="abbreviation"> <rng:text/> </rng:element> </rng:element> </rng:oneOrMore> </rng:element> RELAX NG is a simple yet elegant schema language for XML (see http://www.relaxng.org). The document provinces.xml is valid with regard to this schema, which defines the instance document with a natural, structured hierarchy of definitions. RELAX NG adopts XML Schema datatypes as a datatype library (note the datatypeLibrary attribute on the first element and the rng:data element as a child of rng:attribute). Example 4-9, splat.xsl, is a simple stylesheet that uses name and node tests to analyze the RELAX NG schema. Example 4-9. A stylesheet for analyzing the RELAX NG schema<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rng="http://relaxng.org/ns/structure/1.0"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:value-of select="comment( )"/> <xsl:text> </xsl:text> <xsl:apply-templates select="rng:*"/> </xsl:template> <xsl:template match="rng:*"> <xsl:value-of select="local-name( )"/> <xsl:text>, </xsl:text> <xsl:value-of select="name(@*)"/> <xsl:text> = </xsl:text> <xsl:value-of select="@*"/> <xsl:text> </xsl:text> <xsl:apply-templates select="rng:*"/> </xsl:template> </xsl:stylesheet> Because the elements in the schema are namespace-qualified and use a prefix (rng:), the stylesheet must declare the namespace and prefix as well (xmlns:rng="http://relaxng.org/ns/structure/1.0"). The template that matches the root uses a comment( ) node test to return the text content of a comment in the source. It then applies templates to any element qualified with the RELAX NG namespace (rng:*).
The next template matches on rng:* and reports the names of these elements using the XPath local-name( ) function, which returns the element name without the prefix. The name( ) function returns the names of attributes, if any, using name( ) with @* as an argument; @* is used by itself to return an attribute value. This template uses apply-templates with rng:* again and thereby reports on all RELAX NG elements in the source tree. When applied like this: xalan provinces.rng splat.xsl the text output is: Relax NG schema for provinces.xml element, name = provinces oneOrMore, = element, name = province attribute, name = id data, type = ID element, name = name text, = element, name = abbreviation text, = The first line of the result is the comment at the top of provinces.rng. The remaining lines report the RELAX NG element names followed by the names and values of any attributes the element might have. For more information on name and node tests, see Section 2.3 of the XPath specification. |