]> juplo.de Git - website/blob
97e66e9ff4550afcd834d31e6aab308e7e3a89c0
[website] /
1 ---
2 _edit_last: "2"
3 author: kai
4 categories:
5   - explained
6 date: "2018-09-28T08:38:10+00:00"
7 guid: http://juplo.de/?p=762
8 parent_post_id: null
9 post_id: "762"
10 title: XPath 2.0 deep-equal Does Not Match Like Expected - The Problem With Whitespace
11 url: /xpath-2-0-deep-equal-does-not-match-like-expected-the-problem-with-whitespace/
12
13 ---
14 I just stumbled accros a problem with the `deep-equal()`-method introduced by `XPath 2.0`.
15 It costs me two hours at minimum to find out, what was going on.
16 So I want to share this with you, in case your are wasting time on the same problem and try to find a solution via google ;)
17
18 If you never heard of `deep-equal()` and just wonder how to compare XML-nodes in the right way, you should probably read this [exelent article about equality in XSLT](http://www.xml.com/lpt/a/1589 "Read more about the posibilities to compare nodes in XSLT") as a starter.
19
20 ## My Problem
21
22 My problem was, that I wanted to parse/output a node only, if there exists no node on the `ancestor`-axis, that has a exact duplicate of that node as a direct child.
23
24 ## The Difference Between A Comparison With `=` And With `deep-equal()`
25
26 If you just use simple equality (with `=` or `eq`), the two compared nodes are converted into strings implicitly.
27 That is no problem, if you are comparing attributes, or nodes, that only contain text.
28 But in all other cases, you will only compare the text-contents of the two nodes and their children.
29 Hence, if they differ only in an attribute, your test will report that they are equal, which might not be what you are expecting.
30
31 For example, the XPath-expression
32
33 ```XPath
34 //child/ref[ancestor::parent/ref=.]
35 ```
36
37 will match the `<ref>`-node with `@id='bar'`, that is nested insiede the `<child>`-node in this example-XML, what I was not expecting:
38
39 ```Java
40 <root>
41   <parent>
42     <ref id="foo"><content>Same Text-Content</content></ref>
43     <child>
44       <ref id="bar"><content>Same Text-Content</content></ref>
45     </child>
46   <parent>
47 <list>
48 ```
49
50 So, what I tried, after I found out about `deep-equal()` was the following `Xpath`-expression, which solves the problem in the above example:
51
52 ```XPath
53 //child/ref[deep-equal(ancestor::parent/ref,.)]
54 ```
55
56 ## The Unexpected Behaviour Of `deep-equal()`
57
58 But, moving on I stumbled accross cases, where I was expecting a match, but `deep-equal()` does not match the nodes.
59 For example:
60
61 ```Java
62 <root>
63   <parent>
64     <ref id="same">
65       <content>Same Text-Content</content>
66     </ref>
67     <child>
68       <ref id="same">
69         <content>Same Text-Content</content>
70       </ref>
71     </child>
72   <parent>
73 <list>
74 ```
75
76 You probably catch the diffrenece at first glance, since I laid out the examples accordingly and gave you a hint in the heading of this post - but it really took me a long time to get that:
77
78 ## It is all about whitespace!
79
80 `deep-equal()` compares _all_ child-nodes and only yields a match, if the compared nodes have exactly the same child-nodes.
81 But in the second example, the compared `<ref>`-nodes contain whitespace befor and after their child-node `<content>`.
82 And these whitespace are in fact implicite child-nodes of type text.
83 Hence, the two nodes in the second example differe, because the indentation on the second one has two more spaces.
84
85 ## The solution...?
86
87 Unfortunatly, I do not really know a good solution.
88 (If you come up with one, feel free to note or link it in the comments!)
89
90 The best solution would be an option additional argument for `deep-equal()`, that can be selected to tell the function to ignore such whitespace.
91 In fact, some XSLT-parsers do provide such an argument.
92
93 The only other solution, I can think of, is, to write another XSLT-script to remove all the whitespaces between tags to circumvent this at the first glance unexpected behaviour of `deep-equal()`
94
95 ## Funded by the Europian Union
96
97 This article was published in the course of a
98 [resarch-project](http://yourshouter.com/projekte/crowdgest%C3%BCtzte-veranstaltungs-suchmaschine.html "Show details about the funded resarch-project"),
99 that is funded by the European Union and the federal state Northrhine-Wetphalia.
100
101 [![Europäische Union: Investitionen in unsere Zukunft - Europäischer Fonds für regionale Entwicklung](/img/EFRE_Foerderhinweis_deutsch_farbig.svg)![EFRE.NRW 2014-2020: Invesitionen in Wachstum und Beschäftigung](/img/Ziel2NRW_4c_1809_eps.svg)](http://yourshouter.com/projekte/crowdgest%C3%BCtzte-veranstaltungs-suchmaschine.html "Show details about the funded resarch-project")