Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default namespace declaration with empty string as prefix should not break attribute selection #46

Open
martin-honnen opened this issue Aug 10, 2021 · 6 comments

Comments

@martin-honnen
Copy link
Contributor

martin-honnen commented Aug 10, 2021

The fix suggested some months ago to allow using an empty string as the prefix to select e.g. HTML element in the XHTML namespace unfortunately breaks attribute selection, i.e. a test like

      [Fact]
        public void BindingEmptyPrefixShouldNotBreakAttributeSelection()
        {
            var namespaceManager = new XmlNamespaceManager(new NameTable());
            namespaceManager.AddNamespace("", "http://www.w3.org/1999/xhtml");

            var nodeList = GetXHTMLSampleDoc().XPath2SelectNodes("//@lang", namespaceManager);

            Assert.Equal(1, nodeList.Count);
        }

fails as the XPath2 code now looks for attributes named lang in XHTML namespace. I am currently not sure how to fix the NameTest/QName production in XPath.y to only use the context.NamespaceManager.DefaultNamespace if the node name is of an element node.

@StefH
Copy link
Owner

StefH commented Aug 15, 2021

Just an observation:
https://codebeautify.org/Xpath-Tester

image

image

@StefH
Copy link
Owner

StefH commented Aug 15, 2021

Also note that the original XPath does also not work:

[Fact]
        public void XPath2SelectNodesWithDefaultNamespace()
        {
            var namespaceManager = new XmlNamespaceManager(new NameTable());
            namespaceManager.AddNamespace(string.Empty, "http://www.w3.org/1999/xhtml");

            var nodeListXPath1 = GetXHTMLSampleDoc().SelectNodes("//p", namespaceManager);

            var nodeListXPath2 = GetXHTMLSampleDoc().XPath2SelectNodes("//p", namespaceManager);

            nodeListXPath1.Should().HaveCount(2);
            nodeListXPath2.Should().HaveCount(2);
        }

image

@martin-honnen
Copy link
Contributor Author

Also note that the original XPath does also not work:

[Fact]
        public void XPath2SelectNodesWithDefaultNamespace()
        {
            var namespaceManager = new XmlNamespaceManager(new NameTable());
            namespaceManager.AddNamespace(string.Empty, "http://www.w3.org/1999/xhtml");

            var nodeListXPath1 = GetXHTMLSampleDoc().SelectNodes("//p", namespaceManager);

Well, that is how XPath 1.0 works, no surprise there.

@martin-honnen
Copy link
Contributor Author

Just an observation:
https://codebeautify.org/Xpath-Tester

I don't get through to that page, it wants me to confirm with too many captchas that I am not a robot.

Is that tool using XPath 1, 2 or 3? Or is it using the XPath2 library? I am not sure what the observation is supposed to tell me or explain me.

@StefH
Copy link
Owner

StefH commented Aug 15, 2021

I don't know exactly the difference between v1 en v2 in regard to this specific query, So I assumed that this SelectNodes method should just behave the same.

If that is not the case, then I don't know yet how to solve this.

Question:
Is this special use-case related that you use the default namespace "http://www.w3.org/1999/xhtml"?
So you expect that this default namespace is somehow ignored when selecting the elements with //p ?

@martin-honnen
Copy link
Contributor Author

In XPath 1 p always selects element nodes with local name p in no namespace. In XPath 2 whether p select element nodes with local name p in no namespace or in the default element namespace depends on the static context https://www.w3.org/TR/xpath20/#dt-static-context:

[Definition: Default element/type namespace. This is a namespace URI or "none". The namespace URI, if present, is used for any unprefixed QName appearing in a position where an element or type name is expected.]

Using namespaceManager.AddNamespace(string.Empty, "http://www.w3.org/1999/xhtml"); is supposed (in my opinion) to set the default element namespace for an XPath2 API integrating itself into the XPathNavigator infrastructure of .NET.

The fix achieved that but is currently flawed as attribute selection also is subjected to the namespace supposed to be only the default element namespace declaration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants