具有显式默认命名空间的XML文档的XPath和命名空间规范
发布时间:2020-12-16 05:34:33 所属栏目:百科 来源:网络整理
导读:我正在努力获得XPath表达式和命名空间规范的正确组合,如 XML (参数名称空间)所需,对于在顶部元素上定义了显式xmlns名称空间的XML文档. UPDATE 感谢har07,我能够把它放在一起: 查询名称空间后,ns的第一个条目还没有名称,这就是问题所在: nsDefs - xmlNamesp
我正在努力获得XPath表达式和命名空间规范的正确组合,如
XML (参数名称空间)所需,对于在顶部元素上定义了显式xmlns名称空间的XML文档.
UPDATE 感谢har07,我能够把它放在一起: 查询名称空间后,ns的第一个条目还没有名称,这就是问题所在: nsDefs <- xmlNamespaceDefinitions(doc) ns <- structure(sapply(nsDefs,function(x) x$uri),names = names(nsDefs)) > ns omegahat r "http://something.org" "http://www.omegahat.org" "http://www.r-project.org" 所以我们只需指定一个充当前缀的名称(这可以是任何有效的R名称): names(ns)[1] <- "xmlns" 现在,我们所要做的就是在XPath表达式中的任何地方使用默认名称空间前缀: getNodeSet(doc,"/xmlns:doc//xmlns:b[@omegahat:status='foo']",ns) 对于那些对基于name()和namespace-uri()(以及其他)的替代解决方案感兴趣的人可能会发现this post很有帮助. 仅仅是为了参考:在我们找到解决方案之前,这是试错代码: 考虑一下?xmlParse中的示例: require("XML") doc <- xmlParse(system.file("exampleData","tagnames.xml",package = "XML")) > doc <?xml version="1.0"?> <doc> <!-- A comment --> <a xmlns:omegahat="http://www.omegahat.org" xmlns:r="http://www.r-project.org"> <b> <c> <b/> </c> </b> <b omegahat:status="foo"> <r:d> <a status="xyz"/> <a/> <a status="1"/> </r:d> </b> </a> </doc> nsDefs <- xmlNamespaceDefinitions(getNodeSet(doc,"/doc/a")[[1]]) ns <- structure(sapply(nsDefs,names = names(nsDefs)) getNodeSet(doc,"/doc//b[@omegahat:status='foo']",ns)[[1]] 但是,在我的文档中,名称空间已在< doc>中定义.标签,所以我相应地调整了示例XML代码: xml_source <- c( "<?xml version="1.0"?>","<doc xmlns:omegahat="http://www.omegahat.org" xmlns:r="http://www.r-project.org">","<!-- A comment -->","<a>","<b>","<c>","<b/>","</c>","</b>","<b omegahat:status="foo">","<r:d>","<a status="xyz"/>","<a/>","<a status="1"/>","</r:d>","</a>","</doc>" ) write(xml_source,file="exampleData_2.xml") doc <- xmlParse("exampleData_2.xml") nsDefs <- xmlNamespaceDefinitions(doc) ns <- structure(sapply(nsDefs,names = names(nsDefs)) getNodeSet(doc,"/doc",namespaces = ns) getNodeSet(doc,namespaces = ns)[[1]] 一切都还行.但更重要的是,我的XML代码还具有默认命名空间(xmlns)的显式定义: xml_source <- c( "<?xml version="1.0"?>","<doc xmlns="http://something.org" xmlns:omegahat="http://www.omegahat.org" xmlns:r="http://www.r-project.org">","</doc>" ) write(xml_source,file="exampleData_3.xml") doc <- xmlParse("exampleData_3.xml") nsDefs <- xmlNamespaceDefinitions(doc) ns <- structure(sapply(nsDefs,names = names(nsDefs)) 过去的工作现在失败了: > getNodeSet(doc,namespaces = ns) list() attr(,"class") [1] "XMLNodeSet" Warning message: using http://something.org as prefix for default namespace http://something.org > getNodeSet(doc,"/xmlns:doc",namespaces = ns) XPath error : Undefined namespace prefix XPath error : Invalid expression Error in xpathApply.XMLInternalDocument(doc,path,fun,...,namespaces = namespaces,: error evaluating xpath expression /xmlns:doc In addition: Warning message: using http://something.org as prefix for default namespace http://something.org getNodeSet(doc,namespaces = matchNamespaces(doc,namespaces="xmlns",nsDefs = nsDefs) ) 这似乎让我更接近: > getNodeSet(doc,+ namespaces = matchNamespaces(doc,nsDefs = nsDefs) + )[[1]] <doc xmlns="http://something.org" xmlns:omegahat="http://www.omegahat.org" xmlns:r="http://www.r-project.org"> <!-- A comment --> <a> <b> <c> <b/> </c> </b> <b omegahat:status="foo"> <r:d> <a status="xyz"/> <a/> <a status="1"/> </r:d> </b> </a> </doc> attr(,"class") [1] "XMLNodeSet" 然而,现在我不知道如何进入子节点: > getNodeSet(doc,"/xmlns:doc//b[@omegahat:status='foo']",ns)[[1]] XPath error : Undefined namespace prefix XPath error : Invalid expression Error in xpathApply.XMLInternalDocument(doc,: error evaluating xpath expression /xmlns:doc//b[@omegahat:status='foo'] In addition: Warning message: using http://something.org as prefix for default namespace http://something.org > getNodeSet(doc,+ namespaces = c( + matchNamespaces(doc,nsDefs = nsDefs),+ matchNamespaces(doc,namespaces="omegahat",nsDefs = nsDefs) + ) + ) list() attr(,"class") [1] "XMLNodeSet"
没有前缀的命名空间定义(xmlns =“…”)是默认命名空间.在XML文档具有默认命名空间的情况下,默认命名空间声明的元素和所有它的后代没有前缀且没有不同的默认命名空间声明在上述默认命名空间中被考虑.
因此,在您的情况下,您需要在XPath中的所有元素的开头使用为默认命名空间注册的前缀,例如: /xmlns:doc//xmlns:b[@omegahat:status='foo'] 更新: 实际上我不是r的用户,但是在网上看一些像这样的引用可能有用: getNodeSet(doc,"/ns:doc//ns:b[@omegahat:status='foo']",c(ns="http://something.org")) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |