如何使用CURL和DOM将xml文件中的所有元素放入数组中?

问题描述 投票:1回答:4

我需要一些代码帮助。我希望将使用CURL和DOM的xml文件中的所有元素都放入数组中。

你能帮帮我吗?

我的PHP与CURL代码如下所示:

<?php

$key = 'ad12rqwagst3ewtgsdhdsdsfsdgsd';

$url = 'http://api.11street.my/rest/cateservice/category';

$request_body = 'xml data';

$headers = array(
    'openapikey: ' . $key,
    'Accept-Charset: utf-8',
    'Content-Type: application/xml'
);

$curl = curl_init($url);

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($curl);
$arrXml = array();
$dom = new DOMDocument;
$dom->loadXML($result);

foreach ($dom->getElementsByTagName('dispEngNm') as $item) {
    $arrXml[] = $dom->saveXML($item) . "<br>" . "<hr>";
} 

print_r($arrXml);

?>

xml文件的示例代码如下所示,这些是我拥有的三个项目:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
</ns2:categorys>
<ns2:category>
    <depth>1</depth>
    <dispEngNm>Women Clothing</dispEngNm>
    <dispNm>Women Clothing</dispNm>
    <dispNo>2021</dispNo>
    <parentDispNo>0</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>2</depth>
    <dispEngNm>Women Tops</dispEngNm>
    <dispNm>Women Tops</dispNm>
    <dispNo>2051</dispNo>
    <parentDispNo>2021</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>3</depth>
    <dispEngNm>Tanks &amp; Camisoles</dispEngNm>
    <dispNm>Tanks &amp; Camisoles</dispNm>
    <dispNo>2209</dispNo>
    <parentDispNo>2051</parentDispNo>
</ns2:category>
</ns2:categorys>

输出如下所示:

Array ( [0] => Women Clothing
[1] => Women Tops
[2] => Tanks & Camisoles
[3] => T-shirts

我只能将元素“dispEngNm”放入数组中。任何人都知道如何将其他元素“dispNm”,“dispNo”,“parentDispNo”与“dispEngNm”一起放入数组中?

谢谢你的帮助!祝您有一个愉快的一天!

php arrays xml curl dom
4个回答
0
投票

结合到目前为止的代码并使用SimpleXML的功能轻松迭代子元素,下面的代码首先查找<category>元素(getElementsByTagName()不担心名称空间),然后将其导入SimpleXML,这样你就可以foreach()在子元素上并将它们添加到工作数组中(使用标记名称作为键)。这只是将所有子数据复制到一个关联数组中......

$dom = new DOMDocument;
$dom->loadXML($result);

foreach ($dom->getElementsByTagName('category') as $item) {
    $sxml = simplexml_import_dom($item);
    $newData = [];
    foreach ( $sxml as $tag => $value ) {
        $newData[$tag] = (string)$value;
    }
    $arrXml[] = $newData;
}

print_r($arrXml);

给...

Array
(
    [0] => Array
        (
            [depth] => 1
            [dispEngNm] => Women Clothing
            [dispNm] => Women Clothing
            [dispNo] => 2021
            [parentDispNo] => 0
        )

    [1] => Array
        (
            [depth] => 2
            [dispEngNm] => Women Tops
            [dispNm] => Women Tops
            [dispNo] => 2051
            [parentDispNo] => 2021
        )

    [2] => Array
        (
            [depth] => 3
            [dispEngNm] => Tanks & Camisoles
            [dispNm] => Tanks & Camisoles
            [dispNo] => 2209
            [parentDispNo] => 2051
        )

)

0
投票

只需更改此代码:

foreach ($dom->getElementsByTagName('dispEngNm') as $item) {
    $arrXml[] = $dom->saveXML($item) . "<br>" . "<hr>";
}

通过此代码:

$allTags = $dom->getElementsByTagName('ns2:category');
for ($i =0; $i < $allTags.length; $i++) {
    $childLen = $allTags[i].childNodes.length;
    $innerChilds = $allTags[i].firstChild;
    for ($j = 0; $j < $childLen; $j++) {
        $arrXml[] = $dom->saveXML($innerChilds.innerHTML) . "<br>" . "<hr>"; 
        $innerChilds = $innerChilds.nextSibling;
    }
}

在上面的代码中,我只是加载可能有效的ns2:category的所有子节点。

注意:我还没有测试过代码。您可以测试此项并根据需要进行更改。


0
投票

也许你正在寻找childNodes财产?

$arrXml = array();
foreach($dom->getElementsByTagName("category") as $cat){
    $curr=array();
    foreach($cat->childNodes as $child){
            $curr[$child->nodeName]=$dom->saveXML($child);
    }
    $arrXml[]=$curr;
}
unset($cat,$curr,$child);
print_r($arrXml);

工作实例:

<?php

$xml=<<<'XML'
<ns2:category>
    <depth>1</depth>
    <dispEngNm>Women Clothing</dispEngNm>
    <dispNm>Women Clothing</dispNm>
    <dispNo>2021</dispNo>
    <parentDispNo>0</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>2</depth>
    <dispEngNm>Women Tops</dispEngNm>
    <dispNm>Women Tops</dispNm>
    <dispNo>2051</dispNo>
    <parentDispNo>2021</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>3</depth>
    <dispEngNm>Tanks &amp; Camisoles</dispEngNm>
    <dispNm>Tanks &amp; Camisoles</dispNm>
    <dispNo>2209</dispNo>
    <parentDispNo>2051</parentDispNo>
</ns2:category>
XML;
$dom = new DOMDocument;
@$dom->loadHTML($xml);
$arrXml = array();
foreach($dom->getElementsByTagName("category") as $cat){
    $curr=array();
    foreach($cat->childNodes as $child){
            $curr[$child->nodeName]=$dom->saveXML($child);
    }
    $arrXml[]=$curr;
}
unset($cat,$curr,$child);
print_r($arrXml);
  • 顺便说一句,如果你实际上不想要xml而只是文本内容,那么就改变

$curr[$child->nodeName]=$dom->saveXML($child);

$curr[$child->nodeName]=$child->textContent;

相反,它将包含孩子的文本,而不是xml

顺便说一下这里是带有textContent补丁输出的示例代码:

Array
(
    [0] => Array
        (
            [depth] => 1
            [dispengnm] => Women Clothing
            [dispnm] => Women Clothing
            [dispno] => 2021
            [parentdispno] => 0
        )

    [1] => Array
        (
            [depth] => 2
            [dispengnm] => Women Tops
            [dispnm] => Women Tops
            [dispno] => 2051
            [parentdispno] => 2021
        )

    [2] => Array
        (
            [depth] => 3
            [dispengnm] => Tanks & Camisoles
            [dispnm] => Tanks & Camisoles
            [dispno] => 2209
            [parentdispno] => 2051
        )

)

0
投票

可以通用转换为数组,但大多数情况下您只是松散了功能和数据。 DOM包含Xpath,因此大多数情况下将数据直接读入SPECIFIC数组/对象结构更有意义。在您的情况下,您有一个包含父子关系的记录列表。

您的XML包含名称空间前缀ns2,但缺少其定义。查找属性xmlns:ns2 - 其值是实际的命名空间。

$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:categorys xmlns:ns2="urn:ns2">
<ns2:category>
    <depth>1</depth>
    <dispEngNm>Women Clothing</dispEngNm>
    <dispNm>Women Clothing</dispNm>
    <dispNo>2021</dispNo>
    <parentDispNo>0</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>2</depth>
    <dispEngNm>Women Tops</dispEngNm>
    <dispNm>Women Tops</dispNm>
    <dispNo>2051</dispNo>
    <parentDispNo>2021</parentDispNo>
</ns2:category>
<ns2:category>
    <depth>3</depth>
    <dispEngNm>Tanks &amp; Camisoles</dispEngNm>
    <dispNm>Tanks &amp; Camisoles</dispNm>
    <dispNo>2209</dispNo>
    <parentDispNo>2051</parentDispNo>
</ns2:category>
</ns2:categorys>
XML;

// this needs to be the value of the xmlns:ns2 attribute
$ns_categories = 'urn:ns2';

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// register an prefix for the namespace
$xpath->registerNamespace('c', $ns_categories);

$categories = [];
$tree = [];
// iterate the categories
foreach ($xpath->evaluate('//c:categorys/c:category') as $category) {
    // casting a node list in Xpath will return the content of the first node
    $id = (int)$xpath->evaluate('number(dispNo)', $category);
    $parentId = (int)$xpath->evaluate('number(parentDispNo)', $category);
    // store category data 
    $categories[$id] = [
        'id' => $id,
        'parent_id' => $parentId,
        'depth' => (int)$xpath->evaluate('number(depth)', $category),
        'caption' => $xpath->evaluate('string(dispNm)', $category),
        'caption_english' => $xpath->evaluate('string(dispEngNm)', $category),
    ];
    // store child ids for each parent 
    if (!isset($tree[$parentId])) {
      $tree[$parentId] = [];
    }
    $tree[$parentId][] = $id; 
}

var_dump($categories, $tree);   

主要区别在于,如果您读取泛型转换的结果,则数组键可能具有不同的名称或可能会丢失。结果结构直接取决于输入。如果您将数据读入特定结构(如我的示例),您就知道哪些数组键存在。

© www.soinside.com 2019 - 2024. All rights reserved.