Php XML获取属性
我在overflow中看到了很多教程,但我不明白我遗漏了什么。。所以我需要一些帮助 我有一个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
<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。
}
如果您只想处理id600
,请在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时,如何检查元素标记是否为空?