On 05.04.2018 18:12, Leo Studer leo(_dot_)studer(_at_)varioweb(_dot_)ch wrote:
I have an xml file where I need and XPath expression to find all
elements that are a copy of a previous element in the same file.
I came up with the following:
*let* *$xml* := <a>
<b>
<c>1</c>
<d>1</d>
<d>2</d>
</b>
<b>
<c>2</c>
<d>1</d>
<d>3</d>
</b>
<b>
<c>3</c>
<d>2</d>
<d>3</d>
</b>
<b>
<c>3</c>
<d>2</d>
<d>3</d>
</b>
</a>
*return*
*$xml*//*[*let**$node1*:=.*return**some**$node2**in**$xml*//*[.<<*$node1*]
*satisfies*/deep-equal/(*$node1*,*$node2*)]/(ancestor-or-self::/node/()//concat/(/node-name/(.),1+/count/(preceding-sibling::*)),' ')
which gives
a1 b2 d2
a1 b3 d2
a1 b3 d3
a1 b4
a1 b4 c1
a1 b4 d2
a1 b4 d3
This is actually not to bad. However, I would like the correct position
of the copy. Instead of preceding-sibling::/* /in the count()
function, I would like to write something like
preceding-sibling::/element(node-name(.)). /Unfortunately the processor
does not allow that ;-(…
The code with $xml := <a>...</a> looks like XQuery to me, not like XSLT
or XPath. That aside, what do you want pseudo syntax
preceding-sibling::element(node-name(.))
to compute? If you want to select all elements and compare them to the
node-name() of another node you can certainly use
preceding-sibling::*[node-name() = node-name($n)]
where you simply would need to make sure you define $n previously with a
"let", as you have done at another place in your code.
Also XPath now has a "path" function which returns an XPath expression
with positional predicates so perhaps you don't need to construct the
name/position pairs on your own if you have access to the latest XPath
version.
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--