【问题标题】:XPath to locate element based on attribute value?XPath 根据属性值定位元素?
【发布时间】:2015-09-18 18:42:03
【问题描述】:

我正在尝试搜索我创建的 XML 文档,但我似乎无法让它正常工作。这是我的 XML 文档...

<?xml version="1.0" encoding="UTF-8"?>
<states>
<repstate location="AL">
    <compName>Test Company</compName>
    <name>Chris Brown</name>
    <address>123 Main St</address>
    <city>Anytown</city>
    <state>CT</state>
    <phone>203-123-4567</phone>
    <fax>203-456-7890</fax>
    <email>info@email.com</email>
    <website>www.testing.com</website>
    <serviceArea>All of Alabama</serviceArea>
</repstate>
<repstate location="AK">
    <compName>Test Company</compName>
    <name>Chris Brown</name>
    <address>123 Main St</address>
    <city>Anytown</city>
    <state>CT</state>
    <phone>203-123-4567</phone>
    <fax>203-456-7890</fax>
    <email>info@email.com</email>
    <website>www.testing.com</website>
    <serviceArea>All of Alabama</serviceArea>
</repstate>
</states>

这是我要开始工作的代码 sn-p...

        <?php 
            $xml = simplexml_load_file('../../usa.xml');
            $found = $xml->xpath("//@location='AK'");
            echo $found->state;
        ?>  

它似乎无法正常工作。

我正在尝试在该节点中加载信息。所以所有的compName、姓名、地址、城市、州、电话、传真、电子邮件、网站和服务区。我认为让“状态”工作很容易,但似乎没有任何输出。我做错了什么?

【问题讨论】:

    标签: php xml xpath


    【解决方案1】:

    正如 Micheal Kay 在his answer 中所述,xpath 表达式是有效的。他不知道的是,对于 SimpleXML,这不会导致结果为空。

    因此,当您尝试从空数组中读取字段时,您会看到一个致命错误。您的代码与此类似:

    $found = array();
    echo $found->state;
    

    它回显一个空字符串(由表达式给出的NULL 值创建)和一个通知:

    注意:试图在...中获取非对象的属性

    如果您还没有看到此通知,请务必使用您的开发系统启用错误消息,请参阅 How to get useful error messages in PHP?。

    如您所见,它工作正常,只是没有提供您所期望的。为了以更有成效的方式为自己继续做下去,如果您能分享您所期望的内容,那就太好了。

    或者换句话说:正如其他人也已经回答的那样,您需要决定要查找的内容。

    从输出代码:

    echo $found->state;
    

    我会说您正在寻找以下 XML 元素:

    ...
    <repstate location="AK">
        <compName>Test Company</compName>
        <name>Chris Brown</name>
        <address>123 Main St</address>
        <city>Anytown</city>
        <state>CT</state>
        ...
    

    这就是 SimpleXML Xpath 的工作原理:

    1. 只能查询节点列表
    2. 唯一支持的节点是元素和属性
    3. 列表总是数组类型
    4. 数组始终是零索引
    5. 数组中的每个条目(如果数组不为空)的类型为 SimpleXMLElement

    因此,在您的情况下,如果我对您期望获取的要查询的元素的假设是正确的,则您希望返回单个元素节点的状态子元素节点值。相应的 PHP 代码将是:

    $list = $xml->xpath("//repstate[@location = 'AK']");
    list($repstate) = $list + array(null);
    $state = $repstate ? $repstate->state : '- no such location -';
    
    echo $state;
    

    然后您的 XML 的输出将是:

    CT

    甚至更短:

    $list = $xml->xpath("//repstate[@location = 'AK']/state");
    list($state) = $list + array('- no such location -');
    
    echo $state;
    

    我希望这个更广泛的解释对您有所帮助。你原来的表达行不通的原因是它已经违反了第一点:

    1. 只能查询节点列表

    因为您的 xpath 查询表示布尔表达式而不是节点列表。此外,SimpleXMLElement xpath 中的此类列表需要您有一个元素或属性,并且 not 是一个布尔表达式。

    【讨论】:

      【解决方案2】:

      你还没有说你想要你的 XPath 表达式做什么。您的表达式是有效的,它将返回一个布尔值,如果在文档中的任何位置都有一个等于“AK”的@location 属性,则该值将为真。

      如果要查找@location 属性等于“AK”的元素,请使用//*[@location='AK']。

      【讨论】:

        【解决方案3】:

        除了xpath-表达式本身,xpath 将返回一个 array 的SimpleXML 元素到$found,所以...

        echo $found[0]->state;
        

        或者 - 使用 PHP >= 5.4 - 你可以像这样取消引用数组:

        $found = $xml->xpath(...)[0];
        echo $found->state;
        

        在这里查看:https://eval.in/435965

        【讨论】:

          【解决方案4】:

          我对此不是 100% 肯定,但在 c# 中,xPath 将是:
          //repstate[@location='AK']
          所以你可以试试(我不能把它放进去评论,因为我没有足够高的声誉:))

          【讨论】:

            猜你喜欢
            • 2010-09-18
            • 2020-04-22
            • 1970-01-01
            • 2012-09-30
            • 1970-01-01
            • 1970-01-01
            • 2012-12-08
            • 2012-12-24
            • 1970-01-01
            相关资源
            最近更新 更多