开发者

Short hand for number of tags having lengthier [and almost same] Xpath

开发者 https://www.devze.com 2022-12-24 11:18 出处:网络
For example : this is an xslt <xsl:template match=\"/root/sub-root/parent/child/grand_child/dummy1/dummy2/dummy3/dummy4/node_1

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 [..]

0

精彩评论

暂无评论...
验证码 换一张
取 消