Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php XML获取属性_Php_Xml_Xml Attribute - Fatal编程技术网

Php XML获取属性

Php XML获取属性,php,xml,xml-attribute,Php,Xml,Xml Attribute,我在overflow中看到了很多教程,但我不明白我遗漏了什么。。所以我需要一些帮助 我有一个XML,它是在线的,我试图像这样解析它: <products> <product> <id>13389</id> <name><![CDATA[ product name ]]></name> <category id="14"><![CDATA[ Shoes > t

我在overflow中看到了很多教程,但我不明白我遗漏了什么。。所以我需要一些帮助

我有一个XML,它是在线的,我试图像这样解析它:

<products>
    <product>
    <id>13389</id>
    <name><![CDATA[ product name ]]></name>
    <category id="14"><![CDATA[ Shoes > test1 ]]></category>
    <price>41.30</price>
</products>
$reader = new XMLReader();
$reader->open($product_xml_link);
while($reader->read()) {
if($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'product' ) {
    $product = new SimpleXMLElement($reader->readOuterXml());
    $pid = $product->id;
    $name = $product->name;
    $name = strtolower($name);
    $link = $product->link;
    $price = $product->Price;
    ...
    ...
}
} //end while loop
echo "prodcut= " . (string)$product->category->getAttribute('id');
如您所见,category标记中有一个id。。这是我想要抓取并处理到我的代码中的一个

我是这样做的:

<products>
    <product>
    <id>13389</id>
    <name><![CDATA[ product name ]]></name>
    <category id="14"><![CDATA[ Shoes > test1 ]]></category>
    <price>41.30</price>
</products>
$reader = new XMLReader();
$reader->open($product_xml_link);
while($reader->read()) {
if($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'product' ) {
    $product = new SimpleXMLElement($reader->readOuterXml());
    $pid = $product->id;
    $name = $product->name;
    $name = strtolower($name);
    $link = $product->link;
    $price = $product->Price;
    ...
    ...
}
} //end while loop
echo "prodcut= " . (string)$product->category->getAttribute('id');
我得到的错误是: 调用未定义的方法SimpleXMLElement::getAttribute()

我需要这个id,以便在将其插入数据库之前对其进行测试。。所以

if($id = 600) {
//insert DB
}

这里有几件事。第一个
$product=newsimplexmlement($reader->readOuterXml())
意味着您将所有这些内容作为一个单独的XML文档阅读,然后再次解析。这里是expand(),它将直接返回一个DOM节点,并且可以将DOM节点导入SimpleXML

对于属性,请使用数组语法

$reader = new XMLReader();
$reader->open($product_xml_link);

// an document to expand to
$document = new DOMDocument();

// find the first product node
while ($reader->read() && $reader->localName !== 'product') {
  continue;
}

while ($reader->localName === 'product') {
  $product = simplexml_import_dom($reader->expand($document));
  $data = [
    'id' => (string)$product->id,
    'name' => (string)$product->name,
    'category_id' => (string)$product->category['id'],
    // ...
  ];
  var_dump($data);
  // move to the next product sibling
  $reader->next('product');
}
$reader->close();
输出:

array(3) {
  ["id"]=>
  string(5) "13389"
  ["name"]=>
  string(14) " product name "
  ["category_id"]=>
  string(2) "14"
}
当然,您可以直接使用DOM,并使用Xpath表达式获取详细数据:

$reader = new XMLReader();
$reader->open($product_xml_link);

// prepare a document to expand to
$document = new DOMDocument();
// and an xpath instance to use
$xpath = new DOMXpath($document);

// find the first product node
while ($reader->read() && $reader->localName !== 'product') {
  continue;
}

while ($reader->localName === 'product') {
  $product = $reader->expand($document);
  $data = [
    'id' => $xpath->evaluate('string(id)', $product),
    'name' => $xpath->evaluate('string(name)', $product),
    'category_id' => $xpath->evaluate('string(category/@id)', $product),
    // ...
  ];
  var_dump($data);
  // move to the next product sibling
  $reader->next('product');
}
$reader->close();

是否要循环所有产品,并提取子元素
id
name
link
price
的文本内容?可以这样做:

foreach((@DOMDocument::loadHTML($xml))->getElementsByTagName("product") as $product){
    $vars=array('id','name','link','price');
    foreach($vars as $v){
        ${$v}=$product->getElementsByTagName($v)->item(0)->textContent;
    }
    unset($v,$vars);
    //now you have $id , $name , $link , $price as raw text, and $product is the DOMNode for the <product> tag.
}
foreach((@DOMDocument::loadHTML($xml))->getElementsByTagName(“产品”)作为$product){
$vars=array('id','name','link','price');
foreach($VAR为$v){
${$v}=$product->getElementsByTagName($v)->item(0)->textContent;
}
未结算($v,$vars);
//现在,$id、$name、$link、$price是原始文本,$product是标记的DOMNode。
}
如果您只想处理id
600
,请在unset()之后添加
if($id!=600){continue;}
如果你想节省一些CPU,你也应该插入一个中断;在这种情况下,在foreach循环的末尾。(一旦找到id 600,它将停止循环)

编辑:修复了一个破坏代码的错误,没有错误修复,代码将无法工作

编辑:如果要使用XPath查找正确的元素,它应该是
$product=(新的DOMXpath(@DOMDOcument::loadHTML($xml))->query('//product/id[text()=\'600\']')->item(0)->parentNode


编辑:修复了另一个代码错误(
items(0)
->
items(0)

您好,谢谢您的回答。。请问有没有更简单的方法,不用任何数组?我的代码是这样的,这能抓到身份证吗?不带$document=新DOMDocument();//以及使用$xpath=newdomxpath($document)的xpath实例;或者别的什么?数组只是收集读取数据的一种方式。使用变量,调用函数。。。你可以使用我的FluentDOM库。它扩展了XMLReader/DOM并抽象了其中的一些内容::-)我保留了我的解决方案,并进行了一些更改:$document=$xpath=。我已经删除了代码行:$product=newsimplexmlement($reader->readOuterXml());把我所有的数据都变成了数组。。现在,我看到解析XML有点慢……XML有5.500个产品(不是很多)。在进行任何更改之前,我相信XML的速度要快一些。。有什么建议吗?您好,我终于得到了每个类别的属性id。。现在,还有一个问题。。我已经写了另一个问题,但我还是要写在这里:当元素标记中有CDATA时,如何检查元素标记是否为空?