提问人:Sindo 提问时间:6/9/2023 更新时间:6/9/2023 访问量:71
从 API 读取 XML 的数据过早结束
Premature end of data reading an XML from an API
问:
我从一家公司提供的 API 收到 XML。
当我尝试阅读它时,大多数产品进口都很好——除了这个。
<?xml version="1.0" encoding="utf-8"?>
<pfeed lastaccess="31-12-2010 00:00:00">
<p>
<p_descs lastmodified="1-4-2022 05:28:25">
<p_desc_std_N lastmodified="31-3-2022 00:17:37">
<![CDATA[Test product]]>
</p_desc_std_N>
<p_desc_ext_N lastmodified="31-3-2022 00:21:31">
<![CDATA[<h3>Test product</h3><div class="eq items-block with-gutter items-50-50-100" data-minwidth="" data-maxwidth=""><div class="item item-2"><div class="item-stylable">Lorem ipsum</div></div></div><p><strong>Dolor</strong> justo ultricies vehicula<br /></p>]]>
</p_desc_ext_N>
</p_descs>
</p>
</pfeed>
这里的问题是每个产品都有一个节点 p - /p。在 CDATA 中还有一个 p - /p,
它会导致该产品的导入失败并返回
simplexml_load_string():实体:第 10 行:解析器错误:标记 p 行 2“”“ 中的数据过早结束
如果我删除段落html标签,它运行平稳。
我正在使用 XmlStringStreamer 解析 XML,因为它是 500+ MB。
然后,通过简单的simplexml_load_string读取每个节点
// $node will be a string like this: "<customer><firstName>Jane</firstName><lastName>Doe</lastName></customer>"
try {
$simpleXmlNode = simplexml_load_string( $node );
} catch (\Exception $e) {
echo $e->getMessage();
dd($node);
}
有没有办法忽略CDATA条目中的html?
通过在线解析器拉取 XML 不会引发错误,因为 XML 是正确的 - 但他们也能够毫无问题地读取 XML,所以我认为这是一个小问题,我正在寻找解决方案。
提前致谢。
我尝试了几种方法,例如用 htmlentitities 替换 CDATA 标签中的所有 html 或完全删除段落标签,但都失败了。
答:
0赞
ThW
6/9/2023
#1
这听起来像是 XmlStringStreamer 部件的问题。也许你需要以不同的方式使用它。
读取大型 XML 文件的“标准”工具是 XMLReader。您可以使用它来迭代节点并将它们扩展到 DOM 中。 DOM 可以导入到 SimpleXML 中。p
$reader = new XMLReader();
$reader->open(getXMLURI());
// bootstrap DOM for expanded nodes
$document = new DOMDocument();
$xpath = new DOMXpath($document);
while ($reader->read() && $reader->localName !== 'p') {
continue;
}
while ($reader->localName === 'p') {
// expand to DOM - this will load the current node and all descendants
$p = $reader->expand($document);
// use xpath to access values ...
var_dump($xpath->evaluate('string(p_descs/@lastmodified)', $p));
// ... or nodes ...
foreach ($xpath->evaluate('p_descs/*', $p) as $node) {
var_dump($node->localName, $node->textContent);
}
// ... or import to SimpleXML
$pElement = simplexml_import_dom($p);
// go to following "p" sibling node
$reader->next('p');
}
$reader->close();
function getXMLUri() {
$data = <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<pfeed lastaccess="31-12-2010 00:00:00">
<p>
<p_descs lastmodified="1-4-2022 05:28:25">
<p_desc_std_N lastmodified="31-3-2022 00:17:37">
<![CDATA[Test product]]>
</p_desc_std_N>
<p_desc_ext_N lastmodified="31-3-2022 00:21:31">
<![CDATA[<h3>Test product</h3><div class="eq items-block with-gutter items-50-50-100" data-minwidth="" data-maxwidth=""><div class="item item-2"><div class="item-stylable">Lorem ipsum</div></div></div><p><strong>Dolor</strong> justo ultricies vehicula<br /></p>]]>
</p_desc_ext_N>
</p_descs>
</p>
</pfeed>
XML;
return 'data://text/xml;base64,'.base64_encode($data);
}
评论
0赞
Sindo
6/9/2023
这让我走上了正确的道路!谢谢@ThW!
评论