【问题标题】:PHP retrieving all Node names and node values from a nested XML stringPHP 从嵌套的 XML 字符串中检索所有节点名称和节点值
【发布时间】:2017-10-10 04:58:48
【问题描述】:

试图找到一种方法来读取 XML 文件并获取所有节点。 一些 XML 文件的深度为 1,其他的为 2,其他的更多。 有没有办法在不知道他们名字的情况下为所有孩子获取所有节点? 例如我写了这段代码,但这仅适用于 2 步深度

foreach ($xml->children() as $node) {
        if ($node->children()->count()>0) {
            foreach ($node->children() as $cnode){
                echo $cnode->getName()."<br>";
            }
        }
        echo $node->getName()."<br>";
    }
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" >
   <soap:Header/>
   <soap:Body>
      <multitrans xmlns="http://www.xxxx.xx/">
         <authentication>
            <username>xxxxxx</username>
            <password>xxxxxx</password>
            <clientid>xxxxxx</clientid>
         </authentication>
         <requests>
            <trans_request>
               <TransType tc="100"/>
               <company tc="500"/>
               <product tc="auto"/>
               <inception>
                  <p_year>2017</p_year>
                  <p_month>5</p_month>
                  <p_day>15</p_day>
               </inception>
               <p_number>0</p_number>
               <attributes>
                              <att val="0" name="SVCsynchronouscall" />
                              <att val="2" name="value1" />
                              <att val="2017-5-15" name="Date" />
                              <att val="0" name="value2" />
                              <att val="0" name="value3" />
                              <att val="0" name="value4" />
               </attributes>
<warnings>

</warnings>
            </trans_request>
         </requests>
      </multitrans>
   </soap:Body>
</soap:Envelope>

【问题讨论】:

  • 请分享您的 xml 字符串。
  • @SahilGulati 我已添加到我的问题中
  • 您要提取哪些信息?
  • 我必须获取所有节点名称。例如用户名、密码、clientid、transtype、company、product、p_year 等以及所有属性名称(例如 SVCsynchronouscall、value1 等)
  • 希望我的帖子能帮到你..

标签: php xml simplexml


【解决方案1】:

这里我们使用DOMDocumentDOMXPath 来查找soap:Body 的innerHTML。然后我们在simplexml_load_string 中处理innerHTML 并使用json_encodejson_decode 将其转换为数组,最后我们使用array_walk_recursive 来获取所有值。

Try another code snippet hereDemo for simple xml not-nested

Try this code snippet hereDemo for nested xml

$string = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" >
   <soap:Header/>
   <soap:Body>
      <multitrans xmlns="http://www.xxxx.xx/">
         <authentication>
            <username>xxxxxx</username>
            <password>xxxxxx</password>
            <clientid>xxxxxx</clientid>
         </authentication>
         <requests>
            <trans_request>
               <TransType tc="100"/>
               <company tc="500"/>
               <product tc="auto"/>
               <inception>
                  <p_year>2017</p_year>
                  <p_month>5</p_month>
                  <p_day>15</p_day>
               </inception>
               <p_number>0</p_number>
               <attributes>
                  <att val="0" name="SVCsynchronouscall" />
                  <att val="2" name="value1" />
                  <att val="2017-5-15" name="Date" />
                  <att val="0" name="value2" />
                  <att val="0" name="value3" />
                  <att val="0" name="value4" />
               </attributes>
            <warnings>
            </warnings>
            </trans_request>
         </requests>
      </multitrans>
   </soap:Body>
</soap:Envelope>';
 $finalResult = array();
$domObject = new DOMDocument();
$domObject->loadXML($string);

$domXPATH = new DOMXPath($domObject);
$results = $domXPATH->query("//soap:Body/*");

foreach($results as $result)
{
    if($result->childNodes->length==1 && $result->childNodes->item(0) instanceof  DOMText)
    {
        $finalResult[$result->tagName] = $result->textContent;
    }
    else
    {
        $array = json_decode(json_encode(simplexml_load_string($result->ownerDocument->saveXML($result))), true);
        array_walk_recursive($array, function($value,$key) use(&$finalResult)
        {
            if (!empty($value))
            {
                if(isset($finalResult[$key])&& is_string($finalResult[$key]) )
                {
                    $temp=$finalResult[$key];
                    $finalResult[$key] = array($temp,$value);
                }
                elseif(isset($finalResult[$key]) && is_array($finalResult[$key]) && count($finalResult[$key])>0)
                {
                    $finalResult[$key]=  array_merge(array($value),$finalResult[$key]);
                }
                else
                {
                    $finalResult[$key]=$value;
                }
            }
        });        
    }

}
print_r(array_filter($finalResult));

输出:

 Array
(
    [username] => xxxxxx
    [password] => xxxxxx
    [clientid] => xxxxxx
    [tc] => Array
        (
            [0] => auto
            [1] => 100
            [2] => 500
        )

    [p_year] => 2017
    [p_month] => 5
    [p_day] => 15
    [name] => Array
        (
            [0] => value4
            [1] => value3
            [2] => value2
            [3] => Date
            [4] => SVCsynchronouscall
            [5] => value1
        )

    [val] => Array
        (
            [0] => 2
            [1] => 2017-5-15
        )
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多