【问题标题】:PHP XML losing attributesPHP XML 丢失属性
【发布时间】:2014-09-24 10:29:13
【问题描述】:

我在将 xml 字符串加载到 SimpleXMLElement 时遇到问题(我也尝试使用 DOCDocument,但结果相同)。在 XML 中我有这个:

<definedNames>
        <definedName name="name1" Id="1" hidden="1">NAME_TEST</definedName>
        <definedName name="name2" Id="4" hidden="1">NAME_TEST_2</definedName>
</definedNames>

现在我需要使用“名称”属性访问特定标签。但总是当我尝试 print_r、var_dump 或 smth 时,我总是看到所有其他属性,但是当我看到只有带有

的数组时
[0] = > NAME_TEST, 
[1] =>  NAME_TEST_2 

我也尝试过 xpath,但每次当我引用里面的属性时,我都会得到空数组。

所以现在我尝试了:xpath、SimpleXMLDom、DOCDocument,但结果始终相同 - 空数组。有什么线索吗?

@编辑

$xl->LoadTemplate('#xl/workbook.xml'); 
            if (isset($workbook) && is_array($workbook) && count($workbook > 0)) {
                $dom = new DOMDocument();
                $dom->loadXML($xl->Source);
                $xpath = new DOMXpath($dom);
                foreach ($xpath->evaluate('//definedName') as $definedName) {
                    echo $definedName->getAttribute('name');
                }
            } else {
                $TBS->Source = preg_replace('~\<definedNames\>.*\<\/definedNames\>~', '', $TBS->Source);
            }

@edit2 - xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
 <definedNames>
        <definedName name="name1" Id="1" hidden="1">NAME_TEST</definedName>
        <definedName name="name2" Id="4" hidden="1">NAME_TEST_2</definedName>
</definedNames>
</workbook>

我知道有类似的东西,但我已经尝试过:

$xpath->evaluate('//workbook/definedNames/definedName[@*]')

$xpath->evaluate('/workbook/definedNames/definedName[@name="name1"]')

结果仍然是空的。

【问题讨论】:

    标签: php xml


    【解决方案1】:

    使用 DOMDocument,您可以使用 Xpath 获取值或节点。

    将 XML 加载到文档中并为其创建一个 DOMXpath 实例:

    $dom = new DOMDocument();
    $dom->loadXml($xml);
    $xpath = new DOMXpath($dom);
    

    获取节点值作为字符串:

    var_dump($xpath->evaluate('string(//definedName[@name="name1"])'));
    

    输出:

    string(9) "NAME_TEST"
    

    获取所有definedName元素数据到一个数组中:

    $byName = [];
    foreach ($xpath->evaluate('//definedName') as $definedName) {
      $byName[] = [
        'name' => $definedName->getAttribute('name'),
        'id' => $definedName->getAttribute('Id'),
        'hidden' => $definedName->getAttribute('hidden'),
        'text' => $definedName->nodeValue
      ];
    }
    var_dump($byName);
    

    输出:

    array(2) {
      [0]=>
      array(4) {
        ["name"]=>
        string(5) "name1"
        ["id"]=>
        string(1) "1"
        ["hidden"]=>
        string(1) "1"
        ["text"]=>
        string(9) "NAME_TEST"
      }
      [1]=>
      array(4) {
        ["name"]=>
        string(5) "name2"
        ["id"]=>
        string(1) "4"
        ["hidden"]=>
        string(1) "1"
        ["text"]=>
        string(11) "NAME_TEST_2"
      }
    }
    

    【讨论】:

    • 感谢您的回复。但是我仍然遇到了这个问题,因为 $xpath->evaluate('//definedName') 是空的。在我尝试使用那个 xml 之前,我什至将它保存在 txt 文件中,我可以看到那个 xml 字符串给你看我 1 个帖子。但我仍然无法通过属性访问definedName。
    • 不是,请参阅eval.in/174419 - 您是否发布了整个 XML?它可能包含命名空间。
    • 好的,有命名空间的东西给我一些提示:$xml = str_replace('xmlns=', 'ns=', $xml);
    • 你不应该删除命名空间,在 DOMXpath 上为它们注册一个前缀并使用它。
    【解决方案2】:

    您可以对 SimpleXMLElement 对象的每个元素使用attributes() 方法。然后您可以访问它们:

    $xml = '<definedNames>
            <definedName name="name1" Id="1" hidden="1">NAME_TEST</definedName>
            <definedName name="name2" Id="4" hidden="1">NAME_TEST_2</definedName>
    </definedNames>';
    
    $x = new SimpleXMLElement($xml);
    
    foreach ($x as $element) {
        var_dump($element->attributes());
    }
    

    以上返回:

    object(SimpleXMLElement)#4 (1) {
      ["@attributes"]=>
      array(3) {
        ["name"]=>
        string(5) "name1"
        ["Id"]=>
        string(1) "1"
        ["hidden"]=>
        string(1) "1"
      }
    }
    object(SimpleXMLElement)#3 (1) {
      ["@attributes"]=>
      array(3) {
        ["name"]=>
        string(5) "name2"
        ["Id"]=>
        string(1) "4"
        ["hidden"]=>
        string(1) "1"
      }
    }
    

    然后您可以通过在循环中使用来访问各个属性:

    foreach ($x as $element) {
        $element->attributes()->hidden;
        $element->attributes()->Id;
        $element->attributes()->name;
    }
    

    【讨论】:

    • 嗯,谢谢你的回复,但我尝试了你们提供的smth,结果是一样的。我有 0 个匹配项,当我转储 $x 时,我只看到 NAME_TEST 等没有我需要的属性。
    • 我不知道你在追求什么。当您 var_dump 只是 SimpleXmlElement 它不会显示属性时,您必须使用 attributes() 来访问它们,或者在循环中,或者一个接一个 $x[0]-&gt;attributes()-&gt;hidden;foreach ($x as $element-&gt;attributes()) {echo $x-&gt;Id;}
    【解决方案3】:

    试试simplexml_load_string()

    $p = '<definedNames>
            <definedName name="name1" Id="1" hidden="1">NAME_TEST</definedName>
            <definedName name="name2" Id="4" hidden="1">NAME_TEST_2</definedName>
    </definedNames>';
    $xml = simplexml_load_string($p);
    echo $xml->definedName[0]->attributes()->name;
    echo $xml->definedName[1]->attributes()->name;
    

    或者使用foreach获取所有属性

    【讨论】:

      猜你喜欢
      • 2016-02-27
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多