如何控制用PHP创建的XML中的元素顺序?

时间:2018-07-23 02:17:33

标签: php xml domdocument

我正在用PHP生成XML文档,并且元素必须按特定顺序排列。除三个外,大多数都可以正常工作。子元素如下所示:

  <p>
    <co>ABC</co>
    <nbr>123456</nbr>
    <name>short product description</name>
    <desc>long product description</desc>
    <kw>searchable keywords</kw>
    <i-std>relative/path/to/image</i-std>
    <i-lg>relative/path/to/large/image</i-lg>
    <i-thmb>relative/path/to/thumbnail</i-thmb>
    <mfg>manufacturer</mfg>
    <a-pckCont>package contents</a-pckCont>
</p>

我正在使用的代码可以正常工作,但是三个图像元素混乱,这使得消耗它们的内容处理器感到窒息。我最近最想尝试的是:

$newStd = 0;
foreach ($items as $row => $innerArray) {
    $p = $domTree->createElement('p');
    $xmlRoot->appendChild($p);
    foreach ($innerArray as $innerRow => $value) {
        if ($innerRow != 'key') {
            if ($value != '') {
                echo $innerRow . ' : ' . $value . '<br />';
                if ($innerRow == 'i-std') {
                    $newStd = $domTree->createElement($innerRow, htmlspecialchars($value));
                } else {
                    $p->appendChild($domTree->createElement($innerRow, htmlspecialchars($value)));
                }
            }
        }
        if ($newStd != 0) {
            $thmb = $p->getElementsByTagName('i-thmb')->item(0);
            $p->insertBefore($newStd, $thmb);
        }
    }
}

我的想法是让它在使用InsertBefore编写元素之前先写出所有子元素,以确保它出现在i-thmb元素之前,但这没什么区别。无论我做什么,我得到的输出都会按照i-thmb,i-std,i-lg的顺序排列它们。在重新排列用于构建XML文档的数组中的某些变量之后,所有其他元素都以正确的顺序显示。我还没有尝试控制i-lg元素,因为i-std无法正常工作。

最终,这将用于合并到XML文档中,但是在进行测试以确保XML处理器不会阻塞时,我发现基本问题是元素的顺序在很大程度上决定了它是否可以工作或否(至少可以说,我正在使用的系统没有文档记录,并且支持很差)。

编辑以添加:就像我在内部foreach循环中所做的那样,以正确的顺序显示它们,但是它们在输出文件中不正确。

1 个答案:

答案 0 :(得分:1)

我认为需要进行一些更改才能使代码更健壮(我已在代码中添加了注释,以提供详细信息)。这主要涉及检查数据类型并在每个循环中重置替换字段...

foreach ($items as $row => $innerArray) {
    $p = $domTree->createElement('p');
    $xmlRoot->appendChild($p);
    foreach ($innerArray as $innerRow => $value) {
        $newStd = 0;    // Make sure this is set each time
        if ($innerRow != 'key') {
            if ($value != '') {
                echo $innerRow . ' : ' . $value . '<br />';
                if ($innerRow == 'i-std') {
                    $newStd = $domTree->createElement($innerRow, htmlspecialchars($value));
                } else {
                    $p->appendChild($domTree->createElement($innerRow, htmlspecialchars($value)));
                }
            }
        }
        // Check if a replacement element, checking type of element
        if ($newStd instanceof DOMElement) {
            $thmb = $p->getElementsByTagName('i-thmb')->item(0);
            $p->insertBefore($newStd, $thmb);
        }
    }
}