为啥我的 XPath 返回一个空节点集(带有库 xml2)

Posted

技术标签:

【中文标题】为啥我的 XPath 返回一个空节点集(带有库 xml2)【英文标题】:Why my XPath returns an empty nodeset (with library xml2)为什么我的 XPath 返回一个空节点集(带有库 xml2) 【发布时间】:2021-04-23 00:26:49 【问题描述】:

我想使用 XPath 表达式来获取一些特定的节点。它通常工作正常,但我对这种文件有问题。这是我的 XML 文件的内容:

<?xml version="1.0" encoding="ISO-8859-1"?>
<PROJECT
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.licef.teluq.uquebec.ca/MotPlus
        http://www.licef.teluq.uquebec.ca/xsd/MotPlus.xsd
    "
    xmlns="http://www.licef.teluq.uquebec.ca/MotPlus"
>
    <SUMMARY>
        <TITLE></TITLE>
        <SUBJECT></SUBJECT>
        <CATEGORY></CATEGORY>
        <KEYWORDS></KEYWORDS>
        <FILENAME>test.agdi</FILENAME>
        <AUTHOR></AUTHOR>
        <COPYRIGHT></COPYRIGHT>
        <LICENSE></LICENSE>
        <AUTHENTICITY></AUTHENTICITY>
        <VERSION></VERSION>
        <CREATIONDATE></CREATIONDATE>
        <LASTMODIFYDATE></LASTMODIFYDATE>
        <APPLICATION>MOTPlus</APPLICATION>
        <COMMENTS></COMMENTS>
    </SUMMARY>
    <DOMAINS>
        <DOMAIN id="Domain1" name="Main subject">
            <LABELS>
                <LABEL id="Label1" name="Synchronous" symbol="104"/>
                <LABEL id="Label2" name="Person in a role" symbol="242"/>
                <LABEL id="Label3" name="Index with reference" symbol="63"/>
                <LABEL id="Label4" name="Index without reference" symbol="65"/>
                <LABEL id="Label5" name="Observer" symbol="36"/>
                <LABEL id="Label6" name="Manager" symbol="73"/>
                <LABEL id="Label7" name="Moderator" symbol="54"/>
                <LABEL id="Label8" name="Participant" symbol="33"/>
                <LABEL id="Label9" name="Announcement" symbol="37"/>
                <LABEL id="Label10" name="Hidden" symbol="234"/>
                <LABEL id="Label11" name="Environment" symbol="140"/>
                <LABEL id="Label12" name="Learning object" symbol="141"/>
                <LABEL id="Label13" name="Send Mail" symbol="142"/>
                <LABEL id="Label14" name="Conference" symbol="143"/>
                <LABEL id="Label15" name="Index Search" symbol="144"/>
                <LABEL id="Label16" name="Monitor" symbol="145"/>
                <LABEL id="Label17" name="Learning Activity" symbol="146"/>
                <LABEL id="Label18" name="Support Activity" symbol="147"/>
                <LABEL id="Label19" name="Activity Structure" symbol="148"/>
                <LABEL id="Label20" name="All different individuals" symbol="38"/>
                <LABEL id="Label21" name="One of" symbol="52"/>
                <LABEL id="Label22" name="Union of" symbol="218"/>
                <LABEL id="Label23" name="Intersection of" symbol="217"/>
                <LABEL id="Label24" name="Symetric" symbol="243"/>
                <LABEL id="Label25" name="Transitive" symbol="240"/>
                <LABEL id="Label26" name="Functional" symbol="216"/>
                <LABEL id="Label27" name="Inverse Functional" symbol="215"/>
                <LABEL id="Label28" name="AllValuesFrom" symbol="225"/>
                <LABEL id="Label29" name="Some Values From" symbol="226"/>
            </LABELS>
            <FOLDERS>
                <FOLDER id="Folder1" name="Definition Sub-models"/>
            </FOLDERS>
            <MODELS>
                <MODEL id="Domain1Model1" name="-- Main model --" class="mot">
                    <NODES>
                        <NODE id="Domain1Node1" name="animal" type="concept" x="310.376" y="107.018"  heigth="39.3641" bgColor="16777215" borderColor="0" textColor="0">
                        </NODE>
                        <NODE id="Domain1Node2" name="dog" type="concept" x="310.841" y="188.676"  heigth="39.3641" bgColor="16777215" borderColor="0" textColor="0">
                        </NODE>
                    </NODES>
                    <LINKS>
                        <LINK name="S" type="s" src="Domain1Node1" dest="Domain1Node2" oriented="1" visible="1" linkColor="0">
                        </LINK>
                    </LINKS>
                </MODEL>
            </MODELS>
        </DOMAIN>
    </DOMAINS>
</PROJECT>

这是我在 R 中的代码:

file <- xml2::read_xml(path)
xpath1 <- './/*'
nodes <- xml2::xml_find_all(file, xpath1)
print(nodes)
xpath2 <- './/LABEL'
nodes <- xml2::xml_find_all(file, xpath2)
print(nodes)

我不明白为什么第二个 XPath 返回一个空节点集。我希望得到标题为“标签”的节点。

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

xml 文件定义了一个命名空间。

> xml_ns(file)
d1  <-> http://www.licef.teluq.uquebec.ca/MotPlus
xsi <-> http://www.w3.org/2001/XMLSchema-instance

处理这个问题的最简单方法是剥离命名空间,然后解析文件:

xml_ns_strip(file)
xpath2 <- './/LABEL'
nodes <- xml2::xml_find_all(file, xpath2)
print(nodes)

xml_nodeset (29)
 [1] <LABEL id="Label1" name="Synchronous" symbol="104"/>
 [2] <LABEL id="Label2" name="Person in a role" symbol="242"/>
 [3] <LABEL id="Label3" name="Index with reference" symbol="63"/>
 [4] <LABEL id="Label4" name="Index without reference" symbol="65"/>
 [5] <LABEL id="Label5" name="Observer" symbol="36"/>
...

如果避免剥离命名空间,则在 xpath 中使用正确的命名空间:

ns<-xml_ns(file)
xml2::xml_find_all(file, './/d1:LABEL', ns)

【讨论】:

以上是关于为啥我的 XPath 返回一个空节点集(带有库 xml2)的主要内容,如果未能解决你的问题,请参考以下文章

XPath可以只返回具有X子节点的节点吗?

为啥我的回溯总是返回一个空列表?

Doctrine 存储库返回空结果集

为啥我的 XPath 表达式在 XML 文档中找不到新添加的节点?

使用lxml的Python脚本,xpath返回空列表

为啥 process.env 返回一个空对象,而 process.env.prop 返回 prop 值?