我正在实现相当简单的事情:生成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。它负责转义和编码。
XMLWriterXMLWriter以串行方式工作,它在需要创建/输出大型文档时非常有用。
$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是节点对象的树,表示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']);