生成XML问题

时间:2015-09-16 12:51:56

标签: php xml

我实现了很简单的事情:生成XML,我将发布到设备。 我需要这样的东西:

<field1 parameter1='value1' parameter2='value2'/>
<field2 parameter1='value1' parameter2='value2'/>
<field3>
<subfield1>subvalue1</subfied1>
<subfield2>subvalue2</subfied2>
</field3>

这是我生成它的方式。

$newConfig.="<field1 parameter1='".$_POST['value1']."' parameter2='".$_POST['value2']."' />\n";
$newConfig.="<field2 parameter1='".$_POST['value1']."' parameter2='".$_POST['value2']."' />\n";
$newConfig.="<field3>
<subfield1>".$_POST['subvalue1']."</subfield1>
<subfield2>".$_POST['subvalue2']."</subfield2>
</field3>";

这很好,并且产生了适当的价值。 但是现在,当我用其他值测试它时,由于某种原因它产生了类似的东西(我看起来是配置的var_dump):

<field1 parameter1='value1' parameter2='value2'>
   <field2 parameter1='value1' parameter2='value2'>
   <field3>
   <subfield1>subvalue1</subfield1>
   <subfield2>subvalue2</subfield2>
   </field3>
   </field2>
</field1>

值包含字母,数字,点和@。 怎么可能?什么可以导致它?
更新 我试过DOMDocument,但输出是相同的

<fields>
  <field1 parameter1="value1" parameter2="value2">
  <field2 parameter1="value1" parameter2="value2">
  <field3>
    <subfield1>subvalue1</subfield1>
    <subfield2>subvalue2</subfield2>
  </field3>
</field2></field1></fields>

怎么可能?
UPDATE1 我注意到这个问题只有在我在浏览器中检查元素时,如果我查看页面的源代码,那很好。

<fields>
  <field1 parameter1="value1" parameter2="value2"/>
  <field2 parameter1="value1" parameter2="value2"/>
  <field3>
    <subfield1>subvalue1</subfield1>
    <subfield2>subvalue2</subfield2>
  </field3>
</fields>

那么,什么是实际的xml? 问题是我将它发布到设备上,它运行错误,我应该理解这是不是我的错,或者没有。

1 个答案:

答案 0 :(得分:2)

XML无效。 XML文档需要具有单个文档元素节点。所有其他元素节点必须是该节点的后代。

像这样:

<documentElement>
  <child>
    <childOfChild>...
  </child>
</documentElement>

我想一些解析器试图修复它。它似乎使用第一个元素节点作为文档元素。您可能想要更改XML格式。另外,我建议使用像DOM或XMLWriter这样的XML API。它负责转义和编码。

XMLWriter的

XMLWriter以串行方式工作,如果您需要创建/输出大型文档,它将非常有用。

$writer = new XMLWriter();
$writer->openUri('php://stdout');
$writer->setIndent(2);
$writer->startDocument('1.0', 'UTF-8');

$writer->startElement('fields');

$writer->startElement('field1');
$writer->writeAttribute('parameter1', 'value1');
$writer->writeAttribute('parameter2', 'value2');
$writer->endElement();

$writer->startElement('field2');
$writer->writeAttribute('parameter1', 'value1');
$writer->writeAttribute('parameter2', 'value2');
$writer->endElement();

$writer->startElement('field3');

$writer->startElement('subfield1');
$writer->text('subvalue1');
$writer->endElement();

$writer->startElement('subfield2');
$writer->text('subvalue2');
$writer->endElement();

$writer->endElement();

$writer->endElement();
$writer->endDocument();

输出:

<?xml version="1.0" encoding="UTF-8"?>
<fields>
 <field1 parameter1="value1" parameter2="value2"/>
 <field2 parameter1="value1" parameter2="value2"/>
 <field3>
  <subfield1>subvalue1</subfield1>
  <subfield2>subvalue2</subfield2>
 </field3>
</fields>

该示例将XML写入标准输出。您可以使用XMLWriter::openMemory()XMLWriter::outputMemory()在内存中构建XML并将其写入字符串。

DOM

DOM是一个节点对象树,代表XML。它需要在内存中完成,但它允许操作,而不仅仅是创建。

$document = new DOMDocument();
$document->formatOutput = true;

$fields = $document->appendChild($document->createElement('fields'));

$field = $fields->appendChild($document->createElement('field1'));
$field->setAttribute('parameter1', 'value1');
$field->setAttribute('parameter2', 'value2');

$field = $fields->appendChild($document->createElement('field2'));
$field->setAttribute('parameter1', 'value1');
$field->setAttribute('parameter2', 'value2');

$field = $fields->appendChild($document->createElement('field3'));

$subfield = $field->appendChild($document->createElement('subfield1'));
$subfield->appendChild($document->createTextNode('subvalue1'));

$subfield = $field->appendChild($document->createElement('subfield2'));
$subfield->appendChild($document->createTextNode('subvalue2'));

echo $document->saveXml();

每个节点都知道它的文档,因此您可以轻松地将任务封装到函数/方法中:

function addSubFields($parentNode, array $subFields) {
  $document = $parentNode->ownerDocument;
  foreach ($subFields as $name => $text) {
    $subfield = $parentNode->appendChild($document->createElement($name));
    $subfield->appendChild($document->createTextNode($text));
  }
}

addSubFields($field, ['subfield1' => 'value1', 'subfield2' => 'value2']);