laravel 从API阅读XML的数据过早结束

qlvxas9a  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(83)

我从一家公司提供的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,所以我认为这是一个小问题,我正在研究解决方案。
先谢谢你了。
我尝试了几种方法,比如用htmlentities替换CDATA标记中的所有html,或者完全删除段落标记,但都失败了。

2skhul33

2skhul331#

这听起来像是XmlStringStreamer部件的问题。也许你需要用不同的方式。
阅读大型XML文件的“标准”工具是XMLReader。您可以使用它来迭代p节点并将它们扩展到DOM中。DOM可以导入到SimpleXML中。

$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);
}

相关问题