Introduction to XPath
XPath is a critical component in various XML-related technologies, including XSLT and XPointer. It enables the selection of specific nodes within an XML document using expressions. This capability is essential for transforming XML data, especially when applying XSLT templates to generate structured outputs like HTML or other XML formats.
XPath Expressions and Node Types
XPath expressions define patterns for selecting nodes in an XML document. These nodes include not only elements but also attributes, text, comments, processing instructions, and namespaces. The abstract model defined by XPath includes the following node types:
- Root
- Element
- Text
- Attribute
- Comment
- Processing Instruction
- Namespace
XSLT/XPath Data Model
Similar to the DOM, the XSLT/XPath data model is a tree structure composed of various node types. Under any given element node, there may be text nodes, attribute nodes, element nodes, comment nodes, and processing instruction nodes. This model provides a normalized view of the XML data, where text nodes contain the final resolved values regardless of how they were encoded in the source XML.
XSLT Templates and Context
XSLT templates define how nodes selected by XPath expressions should be transformed. A typical template looks like this:
<xsl:template match="//LIST">
...
</xsl:template>
The expression //LIST selects all LIST elements in the document. The context of the selected nodes determines how other expressions within the template are evaluated. For instance, @type in side the template refers to the type attribute of the current LIST element.
Basic XPath Addressing
XPath expressions resemble directory path notations, allowing hierarchical navigation through XML nodes:
/acts as the path separator.- An absolute path starts with
/. - A relative path starts from the current context.
..refers to the parent node..refers to the current node.
For example, the path /h1/h2 selects all h2 elements that are direct children of h1 elements. To select a specific element, you can use indexing with square brackets: /h1[4]/h2[5] selects the fifth h2 under the fourth h1.
Selecting Attributes
To select attributes, use the @ symbol. For instance, @type selects the type attribute of the current element. Combining this with element selection allows filtering based on attribute values: LIST[@type="unordered"] selects all LIST elements with an unordered type.
Advanced XPath Features
Wildcard Characters
XPath supports wildcard characters to match different types of nodes:
| Wildcard | Description |
|---|---|
* |
Matches any element node |
node() |
Matches any node of any type |
@* |
Matches any attribute node |
Exetnded Path Addressing
Double slashes // are used to select nodes at any level of the hierarchy. For example, //PARA selects all PARA elements in the document regardless of their position. You can also use // within a path, such as /HEAD/LIST//PARA, which selects all PARA elements under /HEAD/LIST and its descendants.
Data Types and Operators
XPath expressions can return a node set, a string, a boolean, or a number. Supported operators include:
|for unionor,andfor logical operations=,!=for equality checks<,>,<=,>=for numeric comparisons+,-,*,div,modfor arithmetic operations
String Values of Elements
The string value of an element is the concatenation of all descendant text nodes. For example, in the following XML:
<PARA>This paragraph contains a <b>bold</b> word</PARA>
The string value of PARA is "This paragraph contains a bold word".
XPath Functions
XPath provides a wide range of functions to manipulate nodes, strings, booleans, and numbers. Some key categories include:
Node Set Functions
id()- Returns a node with a specified ID
Positional Functions
last()- Returns the index of the last nodeposition()- Returns the position of the current nodecount()- Returns the number of nodes in a set
String Functions
concat()- Concatenates stringsstarts-with()- Checks if a string starts with a specified substringcontains()- Checks if a string contains a specified substringsubstring-before(),substring-after()- Extract parts of a stringnormalize-space()- Removes leading and trailing whitespace
Numeric Functions
sum()- Sums the numeric values of a node setfloor(),ceiling(),round()- Mathematical functions
Conversion Functions
string(),boolean(),number()- Convert between data types
Writing DOM as XML
After building a DOM tree, you can serialize it back into an XML document using the XSLT transformation API. This involves creating a Transformer object that connects a DOMSource to a StreamResult.
Reading XML
First, parse the XML file to create a DOM tree:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("input.xml"));
Creating a Transformer
Next, create a transformer and apply it to the DOM:
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
This performs an identity transformation, outputting the original XML without modifications. You can customize the output by setting properties like indentation:
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
Generating XML from Arbitrary Data Structures
You can use a custom parser that generates SAX events to convert non-XML data into XML. For example, a simple parser for an LDIF address book can be transformed in to XML using XSLT:
AddressBookReader saxReader = new AddressBookReader();
FileReader fr = new FileReader("input.ldif");
BufferedReader br = new BufferedReader(fr);
InputSource inputSource = new InputSource(br);
SAXSource source = new SAXSource(saxReader, inputSource);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
Transforming XML with XSLT
XSLT is commonly used to transform XML into HTML or other structured formats. A basic transformation involves defining templates that match specific elements and output corresponding HTML tags:
<xsl:template match="/ARTICLE">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
Handling Inline Elements
For inline elements like <B> or <I>, you can dynamically generate HTML tags using <xsl:element>:
<xsl:template match="B|I|U">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
Conditional Processing
Use <xsl:if> or <xsl:choose> to handle conditional logic, such as generating different list types based on an attribute:
<xsl:template match="LIST">
<xsl:if test="@type='ordered'">
<ol>
<xsl:apply-templates/>
</ol>
</xsl:if>
<xsl:if test="@type='unordered'">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:if>
</xsl:template>
Conclusion
XPath and XSLT provide powerful tools for navigating and transforming XML data. By mastering XPath expressions, XSLT templates, and transformation techniques, you can effectively convert XML into various formats, including HTML, for display or further processing.