Short hand for number of tags having lengthier [and almost same] Xpath
For example : this is an xslt
<xsl:template match="/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_1
|/root/sub-root/parent/child/grand_child/dummy1/dummy开发者_如何学JAVA2/dummy3/dummy4/node_2
|/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_3
.
.
|/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_N"/>
In the above code can I use the XPath
/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4
only once [use the braces or whatever] and reduce the bulkiness of the code?
As you can see, all the nodes are siblings of each-other, so except their name their Xpath is same. Is there any short-hand property ?
Does XSLT 1.0 (or Xpath1.0) allows it?
Ask yourself if the long specific match expression is really necessary. I see that this is an example only, but you don't really have to include the complete path to the element, only as much as necessary to make it unambiguous.
Further, I remind you of the self
axis:
<xsl:template match="/.../dummy4/*[self::node_1 or self::node_2 ...]" />
If the name is structured and predictable, you can do
<xsl:template match="/.../dummy4/*[substring-before(name(), '_') = 'node']" />
Does XSLT 1.0 (or Xpath1.0) allows it?
The following is a correct XPath 1.0 expression:
root/sub-root/parent/child/grand_child
/dummy1/dummy2/dummy3/dummy4
/*
[starts-with(name(), 'node_')
and
substring-after(name(), 'node_') >= 1
and
not(substring-after(name(), 'node_') > $N)
]
However, match patterns are only a subset of all XPath expressions and certain restrictions apply on them. In particular, in XSLT 1.0 they cannot contain a reference to an xsl:variable.
In case the value N is statically known, then one will substitute this literal value (say 1000) in the above XPath expression, and thus have a valid XSLT 1.0 match pattern.
Do note that this is an extreme case and it is extremely unlikely in any practical circumstances to need such a long match pattern. By definition, a match pattern doesn't need to specify the complete path to the node -- only a sufficient "from-right-subpath" that disambiguates the node from other nodes with the same name that must be processed by a different template.
So, in most cases even the following will be sufficient:
*
[starts-with(name(), 'node_')
and
substring-after(name(), 'node_') >= 1
and
not(substring-after(name(), 'node_') > {N})
]
where {N} must be replaced by a integer literal -- the actual value of $N.
Or, in the easiest case (happens quite often), if there are four nodes and no disambiguation is necessary, one would just use:
node_1|node_2|node_3|node_4
Only tested it in an online xpath tool, so not entirely sure, but it should work
<xsl:template match="/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node()[name() = 'node_1' or name()='node_2' ... or name()='node_N']"/>
If there aren't any nodes in dummy4 you want to omit, just drop the [..]
精彩评论