XML中的硬编码字符串已损坏


Hardcoded string in XML gets corrupted

这里有一个奇怪的。。。在PHP中通过几行循环生成的XML提要中,一个HARDCODED字符串在一个位置上发生变化。

生成的XML文件是36000多行。在第8020行发生以下情况:

<g:google_product_category>Home &amp; Garden &gt; Decor &gt; Window Treatments &gt; Curtains &amp; Drapes</g:google_product_category>

更改为(注意:为了清晰起见,我在此处添加了星号):

<g:google_product_category>Home &amp; Garden &gt; Decor &gt; Window Treatments **&ggt;** Curtains &amp; Drapes</g:google_product_category>

奇怪的是,这行没有包含任何可能损坏的变量。它是一个硬编码字符串,请参见下文。这怎么可能?该行在XML文件中出现751次。只有一个地方会发生这种情况。

在多次运行XML生成器时,会发生相同类型的错误,但不会发生在同一位置。随机"html安全字符"(如&gt;&将一个字母复制到&ggt;或&aamp;

XML不是作为对象生成的,而是由一个for循环生成的,该循环构建了一个字符串,如下所示:

$ret .= "<item>'n";
$ret .= "<g:id>ft-".$row["entry_id"]."</g:id>'n";
$ret .= "<g:title>".$row["title"]."</g:title>'n";
$ret .= "<g:description>".$row["description"]."</g:description>'n";
$ret .= "<g:link>http://www.example.com/sidor/fototapet/".$row["entry_id"]."?google=true</g:link>'n";
$ret .= "<g:image_link>http://www.example.com/".$this->get_filename($row2["field_id_6"],$row["entry_id"])."</g:image_link>'n";
$ret .= "<g:condition>new</g:condition>'n";
$ret .= "<g:availability>in stock</g:availability>'n";
$ret .= "<g:price>". ceil(280*$price_mod) ."</g:price>'n";
$ret .= "<g:google_product_category>Home &amp; Garden &gt; Decor &gt; Window Treatments &gt; Curtains &amp; Drapes</g:google_product_category>'n";
$ret .= "<g:product_type>Fototapet</g:product_type>'n";
$ret .= "</item>'n";

我认为如果不完全访问源代码和调试工具,就不可能发现问题。你的问题没有提供足够的信息。

但是:如果生成一个大的XML,则应该直接将其写入文件中。

如果将XML生成为文本,则需要转义动态值,如$row['entry]htmlspecialchars()可以为您做到这一点。

下面是用于此任务的XML API-XMLWriter。以下是一个精简示例:

$xmlns = [
  'g' => 'urn:google-namespace'
];
$writer = new XMLWriter;
$writer->openURI('php://output');
$writer->startDocument('1.0', 'UTF-8');
$writer->setIndent(2);
$writer->startElement('rss');
$writer->startElement('item');
$writer->writeElementNS('g', 'item', $xmlns['g'], 'id-from-db');
$writer->endElement();
$writer->endElement();
$writer->endDocument();

输出:

<?xml version="1.0" encoding="UTF-8"?>
<rss>
 <item>
  <g:item xmlns:g="urn:google-namespace">id-from-db</g:item>
 </item>
</rss>