生成XML问题


Generation of XML issues

我正在实现相当简单的事情:生成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>";

这工作得很好,正在生成适当的值。但是现在,当我用其他值测试它时,由于某种原因,它生成了类似于(我查看config的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?问题是我把它发布到设备上,它工作错误,我应该明白这是我的错,还是没有。

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']);