-
Notifications
You must be signed in to change notification settings - Fork 96
Description
Hello,
I'm trying to select duplicate nodes by looking value of one specific child. Normally I should be able to do that by using the following XPath:
/response[@status="success"]/result/entry[username][domain][username=following-sibling::entry/username or username=preceding-sibling::entry/username]
However when I try to use that XPath in xmlquery, I've faced that "following-sibling" and "preceding-sibling" axes are just making a lookup for one nodes forward or backward I believe, not looks for all following or preceding nodes! (It should do due to XPath2.0 specification.)
Here is the proof of the use of axes in my Xpath is valid: http://xpather.com/dO1pwotO
I also tested that XPath with Xmplify app.
This is the sample XML file that I would like to show the issue:
<!--test1.xml-->
<response status="success">
<result>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
<entry>
<domain>domain</domain>
<username>test2</username>
</entry>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
<entry>
<domain>domain</domain>
<username>test2</username>
</entry>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
</result>
</response>And sample code to reproduce the issue:
package main
import (
"fmt"
"os"
"github.com/antchfx/xmlquery"
)
func main() {
file, err := os.Open("./test2.xml")
// file, err := os.Open("./test2.xml")
if err != nil {
panic(err)
}
defer file.Close()
xml, err := xmlquery.Parse(file)
if err != nil {
panic(err)
}
result := xmlquery.FindOne(xml, "/response[@status=\"success\"]/result")
if result == nil {
panic("Not an expected XML File!")
}
for _, iter := range xmlquery.Find(result, "/entry[username][domain][username=following-sibling::entry/username or username=preceding-sibling::entry/username]") {
username := iter.SelectElement("username").InnerText()
domain := iter.SelectElement("domain").InnerText()
fmt.Println("FOUND/SELECTED NODE: \tUSERNAME=" + username + "\tDOMAIN=" + domain)
}
}This code outputs nothing because range for loop won't run since xmlquery.Find can't find anything.
➜ go run test.go #test1.xml
➜ However when I try the very same code with another xml sample (which is basically the same, only order is different), code works since xmlquery.Find find duplicate nodes because they are consecutive. But not all again, I'll explain below!
<!--test2.xml-->
<response status="success">
<result>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
<entry>
<domain>domain</domain>
<username>test1</username>
</entry>
<entry>
<domain>domain</domain>
<username>test2</username>
</entry>
<entry>
<domain>domain</domain>
<username>test2</username>
</entry>
</result>
</response>The output is:
➜ go run test.go #test2.xml
FOUND/SELECTED NODE: USERNAME=test1 DOMAIN=domain
FOUND/SELECTED NODE: USERNAME=test1 DOMAIN=domain
FOUND/SELECTED NODE: USERNAME=test1 DOMAIN=domain
FOUND/SELECTED NODE: USERNAME=test2 DOMAIN=domain
➜ Here now the very same code can find something. To be exact all 3 duplicates for "test1" but only ONE of 2 duplicate of "test2".
However, in each case, I was expecting to find 5 records! This is also weird. Please check it with xpather.com by yourself.
I'm not sure if it is a bug for antchfx/xmlquery or antchfx/xpath but anyway I submitted the issue here.