【问题标题】:PHP simplexmlelement fails to find attribute when attribute path is assigned to variable将属性路径分配给变量时,PHP simplexmlelement 找不到属性
【发布时间】:2021-05-01 00:36:08
【问题描述】:

我的代码解析一个数组以获取 xml 文件中各种属性的路径。我将 xml 作为 simplexmlelement 加载,如下所示:

$xml = simplexml_load_string($xml_string);
$address = $xml->response->addressinformation->records->record[0];

此代码将起作用并显示正确的 '03' 值:

$from = $address->{'from-date'}['month'];
echo $from;

//prints '03'

from-date 周围的 {} 是必需的,因为元素名称中包含 -

下面的代码块看起来应该在功能上等同于上面的代码,但是当我将路径分配给 $variable 时它不起作用。

$path = "{'from-date'}['month']";
$from = $address->$path;
echo $from;

//prints ''
$path = "from-date['month']";
$from = $address->$path;
echo $from;

//prints ''

此代码将起作用。

//normal path
$from = $address->{'from-date'};

//path assigned to variable
$path = "from-date";
$from2 = $address->$path;

var_dump($from);
var_dump($from2);

//both correctly output - object(SimpleXMLElement)#1587 (1) 
//{ ["@attributes"]=> array(2) { ["year"]=> string(4) "2003" ["month"]=> string(2) "03" } }

只有当我使用['month'] 定位特定属性时,它似乎才会失败。我知道这个问题的答案只是我做错了一些愚蠢的事情。谁能告诉我这是什么?

示例 XML

$xml_string = '
<?xml version="1.0" encoding="utf-8"?>
<root>
    <response>
        <addressinformation>
            <records>
                <record id="1">
                    <fullname>JOHN E DOE</fullname>
                    <firstname>JOHN</firstname>
                    <middlename>E</middlename>
                    <lastname>DOE</lastname>
                    <fulldob>01/01/1970</fulldob>
                    <from-date year="2003" month="03"/>
                    <to-date year="2010" month="09"/>
                </record>
                <record id="2">
                    <fullname>JOHN E DOE</fullname>
                    <firstname>JOHN</firstname>
                    <from-date year="2003" month="03"/>
                    <to-date year="2010" month="09"/>
                </record>
            </records>
        </addressinformation>
        <otherinformation>
            <records>
                <record id="3">
                    <fullname>JOHN DOE</fullname>
                    <firstname>JOHN</firstname>
                    <lastname>DOE</lastname>
                    <fulldob>01/01/1970</fulldob>
                </record>
                <record id="4">
                    <fullname>JOHN EDWARD DOE</fullname>
                    <firstname>JOHN</firstname>
                    <middlename>EDWARD</middlename>
                    <lastname>DOE</lastname>
                    <fulldob>19700000</fulldob>
                </record>
                <record id="5">
                    <fullname>JOHN EDWARD DOE</fullname>
                    <firstname>JOHN</firstname>
                    <middlename>EDWARD</middlename>
                    <lastname>DOE</lastname>
                    <fulldob>19830000</fulldob>
                </record>
            </records>
        </otherinformation>
    </response>
</root>
';

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    你不能使用像"from-date['month']" 这样的东西作为元素的路径,就像你不能在普通数组中使用它一样。预计它只是数组的 1 级。

    XML 的另一种选择是您可以使用 XPath 表达式(您需要学习 XPath,但如果您使用 XML,它可能会解决很多其他问题)。

    你的情况……

    $path = "./from-date/@month";
    $from = $address->xpath($path)[0];
    echo $from;
    

    03

    XPath 行中[0] 的原因是xpath() 返回一个匹配数组,所以这里只选择第一个。

    (顺便说一句,&lt;?xml ... 之前也不应该有任何空格,所以请确保你有类似的东西

    $xml_string = '<?xml version="1.0" encoding="utf-8"?>
    

    )

    【讨论】:

      【解决方案2】:

      您尝试做的事情是不可能的;您只能使用一个变量作为您尝试访问的属性的名称,而不是将其作为数组引用。当你尝试使用

      $path = "{'from-date'}['month']";
      $from = $address->$path;
      

      您实际上是在尝试访问名称为 {'from-date'}['month'] 的对象属性,这就是您没有得到任何结果的原因。

      您也可以使用变量指定属性:

      $path = "from-date";
      $attr = 'month';
      $from2 = $address->$path[$attr];
      echo $from2;
      

      哪个会输出

      03
      

      根据需要。

      【讨论】:

      • 感谢尼克。完全有道理。我假设我使用的路径只是一个用于定位笔记的字符串 simplexml。我不能做我正在做的事情,原因与我不能做$path = 'path-&gt;to-&gt;some-&gt;node'; $node = $address-&gt;$path 的原因相同。不知道为什么我昨晚无法自己弄清楚。感谢您的帮助!
      • @RyanRobinson 考虑到 simplexml 的工作方式,这并不是一个完全不合理的假设。毕竟,如果你用一个普通的对象来尝试过,你会得到一个未定义的属性错误。无论如何,我很高兴这很有用。
      猜你喜欢
      • 2016-09-27
      • 2021-12-02
      • 1970-01-01
      • 2016-12-24
      • 2021-09-20
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多