xsl-list
[Top] [All Lists]

Re: [xsl] XPath to find duplicate elements

2018-04-05 11:45:45
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::*)),'&#10;')

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
--~--

<Prev in Thread] Current Thread [Next in Thread>