How XPath Wildcards Asterisk and @* Work
XPath wildcards allow you to query XML documents when element or
attribute names are unknown, variable, or need to be selected
collectively. In XML XPath navigation, the principal wildcards are the
asterisk (*) for element nodes and the at-asterisk
(@*) for attribute nodes. This guide explains how these
wildcards function, their syntax, and practical examples of their usage
in navigating XML data structures.
The Element Wildcard: *
The asterisk (*) wildcard matches any element
node at the specified location path, regardless of its tag
name. It does not select text nodes, comments, processing instructions,
or attributes.
Common Usage Patterns for
*
- Selecting direct children:
/bookstore/*selects all child elements directly beneath the<bookstore>root element, regardless of whether they are<book>,<magazine>, or<author>tags. - Selecting all descendant elements:
//*selects every element node in the entire XML document. - Selecting grandchild elements:
/bookstore/*/*selects all elements that are children of any child of<bookstore>. - Combining with predicates:
/*[name() = 'catalog']matches the root element only if its name matches the condition.//book/*selects all child elements inside any<book>element, which is useful for extracting all sub-fields without knowing their specific tag names in advance.
The Attribute Wildcard:
@*
The at-asterisk (@*) wildcard matches any
attribute node within an element. It ignores the
specific attribute name and targets the attribute itself or tests for
its presence.
Common Usage Patterns for
@*
- Selecting all attribute values:
//@*selects every attribute of every element across the entire XML document.//book/@*selects all attributes belonging to any<book>element (such asid,category, orlang). - Filtering elements that have at least one
attribute:
//book[@*]matches any<book>element that contains at least one attribute, regardless of the attribute’s name or value. - Matching elements with a specific attribute value:
//*[@*='fiction']matches any element where any attribute contains the exact string value"fiction".
Differences Between
*, @*, and node()
To avoid common pitfalls in XML navigation, it is important to distinguish between wildcards and node-type tests:
| Pattern | Target Match | Ignores |
|---|---|---|
* |
Any element node | Attributes, text, comments, processing instructions |
@* |
Any attribute node | Element nodes, text, comments |
node() |
Any node type (elements, text, comments) | Attribute nodes |
Practical XML Example
Consider the following XML snippet:
<store>
<product id="101" category="electronics">
<name>Laptop</name>
<price currency="USD">999.99</price>
</product>
<product id="102">
<name>Desk</name>
<price>149.99</price>
</product>
</store>/store/product/*returns<name>Laptop</name>,<price>,<name>Desk</name>, and<price>.//product/@*returns the attributesid="101",category="electronics", andid="102".//price[@*]returns only<price currency="USD">999.99</price>because it possesses an attribute, whereas the second<price>element does not.//*[@category]vs//*[@*]: The former matches elements with a specificcategoryattribute, while//*[@*]matches both<product>elements and the first<price>element because all three contain at least one attribute.