.NET: Is there a way to resolve the default namespace in an XPath 1.0 query?

I am creating a tool that executes xpath 1.0 requests on XHTML documents. Requiring to use a namespace prefix in a query kills me. The request is as follows:

html/body/div[@class='contents']/div[@class='body']/
    div[@class='pgdbbyauthor']/h2[a[@name][starts-with(.,'Quick')]]/
    following-sibling::ul[1]/li/a

(all in one line)

... which is bad enough, except that it is xpath 1.0, I need to use an explicit namespace prefix for each QName, so it looks like this:

ns1:html/ns1:body/ns1:div[@class='contents']/ns1:div[@class='body']/
    ns1:div[@class='pgdbbyauthor']/ns1:h2[ns1:a[@name][starts-with(.,'Quick')]]/
    following-sibling::ns1:ul[1]/ns1:li/ns1:a

To set up a query, I do something like this:

var xpathDoc = new XPathDocument(new StringReader(theText));
var nav = xpathDoc.CreateNavigator();
var xmlns = new XmlNamespaceManager(nav.NameTable);
foreach (string prefix in xmlNamespaces.Keys)
    xmlns.AddNamespace(prefix, xmlNamespaces[prefix]);    
XPathNodeIterator selection = nav.Select(xpathExpression, xmlns);

But I want xpathExpression to use the default implicit namespace.

Is there a way to convert an unmanaged xpath expression after it is written to introduce a namespace prefix for each element name in the request?

, - , . , "parent::" "previous-sibling::". . , " finagle ".

?



. , xpath, , nav.Select(), . - :

string FixupWithDefaultNamespace(string expr)
{
    string s = expr;
    s = Regex.Replace(s, "^(?!::)([^/:]+)(?=/)", "ns1:$1");                        // beginning
    s = Regex.Replace(s, "/([^/:]+)(?=/)", "/ns1:$1");                             // stanza
    s = Regex.Replace(s, "::([A-Za-z][^/:*]*)(?=/)", "::ns1:$1");                  // axis specifier
    s = Regex.Replace(s, "\\[([A-Za-z][^/:*\\(]*)(?=[\\[\\]])", "[ns1:$1");        // predicate
    s = Regex.Replace(s, "/([A-Za-z][^/:]*)(?!<::)$", "/ns1:$1");                  // end
    s = Regex.Replace(s, "^([A-Za-z][^/:]*)$", "ns1:$1");                          // edge case
    s = Regex.Replace(s, "([-A-Za-z]+)\\(([^/:\\.,\\)]+)(?=[,\\)])", "$1(ns1:$2"); // xpath functions

    return s;
}

, . - xpath, , , , ns1. , , Regex.Replace , xpath ?

+3
4

, (.. XHTML) , , XmlTextReader, , :

            XmlTextReader tr = new XmlTextReader(new StringReader(@"<html xmlns=""http://www.w3.org/1999/xhtml"">
  <head>
    <title>Test</title>
  </head>
  <body>
    <h1>Example</h1>
  </body>
</html>"));
            tr.Namespaces = false;
            XPathDocument doc = new XPathDocument(tr);
            tr.Close();
            Console.WriteLine(doc.CreateNavigator().SelectSingleNode("html/body/h1").Value);

"", "html/body/h1" "h1". , .

, , Microsoft XPath 1.0, XPath 2.0 XQuery 1.0, Saxon XQSharp. XPath XQuery XHTML.

+2

, XPath W3C :

"QName node , . , xmlns : QName , URI NULL ( ). , QName , ."

"" XPath, , , , , XPath , , - , -. , ( "/"), "/" .

(), , :

div div div

XPath , , , , , RegExes .

+2

, : xmlns.

. xml , , XPathDocument:

xml = xml.Replace(" xmlns="," xxxxx=");

( 0.00065 93kb .)

XPath .

+1

, , . Stackoverflow :

    s = Regex.Replace(s, "^(?!(::|([A-Za-z][-A-Za-z]+\\(.+\\))))([^/:]+)(?=/)", prefix + ":$1");                             // beginning
    s = Regex.Replace(s, "/([^\\.^@^/:\\*\\(]+)(?=[/\\[])", "/" + prefix + ":$1"); //segment with fixed attribute
    s = Regex.Replace(s, "(child|descendant|ancestor|ancestor-or-self|descendant-or-self|self|parent|following|following-sibling|preceding|preceding-sibling)::((?!([\\w]*\\(\\)))[A-Za-z][^/:*]*)((?=/)|(?=\\b))", "$1::" + prefix + ":$2");                  // axis specifier
    s = Regex.Replace(s, "\\[([A-Za-z][^/:*\\(]*)(?=[\\[\\]])", "[" + prefix + ":$1");        // within predicate
    s = Regex.Replace(s, "/([A-Za-z][^/:\\*\\(]*)(?!<::)$", "/" + prefix + ":$1");               // end
    s = Regex.Replace(s, "^([A-Za-z][^/:]*)$", prefix + ":$1");                               // edge case
    s = Regex.Replace(s, "([A-Za-z][-A-Za-z]+)\\(([^\\.^@^/:\\.,\\(\\)]+)(?=[,\\)])", "$1(" + prefix + ":$2"); // xpath functions with fixed attributes
0

Source: https://habr.com/ru/post/1739486/


All Articles