Re: [xsl] XPath to find duplicate elements

Subject: Re: [xsl] XPath to find duplicate elements
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 5 Apr 2018 16:45:39 -0000
On 05.04.2018 18:12, Leo Studer leo.studer@xxxxxxxxxxx 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::*)),'&#10;')

which gives

 B a1 b2 d2
 B a1 b3 d2
 B a1 b3 d3
 B a1 b4
 B a1 b4 c1
 B a1 b4 d2
 B 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,B I would like to write something like preceding-sibling::/element(node-name(.)). /Unfortunately the processor does not allow that ;-(b&

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.

Current Thread