antchfx / xmlquery

xmlquery is Golang XPath package for XML query.
https://github.com/antchfx/xpath
MIT License
444 stars 89 forks source link

Query leads to empty result after switching from v1.3.14 to v1.3.15 #104

Closed JonasDoe closed 1 year ago

JonasDoe commented 1 year ago

The function prints a different result length (1) vs (0), depending on the version of xmlquery

func BreakingChange() {
  xmlContent := `
    <?xml version="1.0"?>
    <rdf:RDF xmlns="http://www.w3.org/2002/07/owl#"
    xml:base="http://www.w3.org/2002/07/owl"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:xml="http://www.w3.org/XML/1998/namespace"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
    <Ontology rdf:about="http://www.my-company.io/ontologies"/>
    <AnnotationProperty rdf:about="http://www.my-company.io/ontologies#serviceEntity">
    </AnnotationProperty>

    <Class rdf:about="http://www.my-company.io/ontologies#MyEntity">
    </Class>
    <Axiom>
      <annotatedSource rdf:resource="http://www.my-company.io/ontologies#MyEntity"/>
    </Axiom>
    </rdf:RDF>
  `
  source, err := xmlquery.Parse(bytes.NewReader([]byte(xmlContent)))
  if err != nil {
    panic(err)
  }
  axioms, err := xmlquery.QueryAll(source, "rdf:RDF/owl:Axiom/owl:annotatedSource[@rdf:resource='http://www.my-company.io/ontologies#MyEntity']/parent::owl:Axiom")

  fmt.Printf("found axioms: %d\n", len(axioms)) // prints "found axioms: 1" in v1.3.14 and "found axioms: 0" in v1.3.15
}

I apologize for the messy look - I tried to strip most unnecessary from a rather huge rdf file but keep some essential information to give an idea about the xml type.

I've also noticed there's another issue about a breaking change, but your recommended commit 0f42df8 doesn't fix the behavior I've observed here.

zhengchun commented 1 year ago

Use CompileWithNS() to specified NamespaceURL.

expr, _ := xpath.CompileWithNS("rdf:RDF/owl:Axiom/owl:annotatedSource[@rdf:resource='http://www.my-company.io/ontologies#MyEntity']/parent::owl:Axiom", map[string]string{
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "owl": "http://www.w3.org/2002/07/owl#",
    })
    axioms = xmlquery.QuerySelectorAll(source, expr)

Considing rollback v1.3.14 version for default NamespaceURL, may be will not.

zhengchun commented 1 year ago

The above method still can work with by NamespaceURL(xpath v1.2.4).

In the latest commit, changedaxioms, err := xmlquery.QueryAll(source, "rdf:RDF/owl:Axiom/owl:annotatedSource[@rdf:resource='http://www.my-company.io/ontologies#MyEntity']/parent::owl:Axiom")

to

axioms, err := xmlquery.QueryAll(source, "rdf:RDF/Axiom/annotatedSource[@rdf:resource='http://www.my-company.io/ontologies#MyEntity']/parent::Axiom")

if your XML file include prefix like this

    <owl:Axiom>
      <owl:annotatedSource rdf:resource="http://www.my-company.io/ontologies#MyEntity"/>
    </owl:Axiom>

yes ,you can use rdf:RDF/owl:Axiom/owl:annotatedSource[@rdf:resource='http://www.my-company.io/ontologies#MyEntity']/parent::owl:Axiom