我想创建一个具有非常特定格式的XML文档。它看起来应该类似于:
<?xml version="1.0" encoding="UTF-8"?>
<ram:FLOW xmlns:ram=\"http://MY_LIBRARY\" xmlns:mar=\"http://ANOTHER_LIBRARY\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
<Header>
<Source>Application1</Source>
<Time>2014-11-12T12:46:39</Time>
<Environment>TEST</Environment>
<Sequence>537</Sequence>
</Header>
<Data>
<mar:OC_DC>
<DC_elements>
<Unit>
<Unit_ID>089789</Unit_ID>
<State>active</State>
</Unit>
<Unit>
<Unit_ID>459008</Unit_ID>
<State>inactive</State>
</Unit>
</DC_elements>
</mar:OC_DC>
</Data>
</ram:FLOW>
我写了一个PHP / MySQL脚本来生成这个文档:
<?php
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"UTF-8\"?><ram:FLOW xmlns:ram=\"http://MY_LIBRARY\" xmlns:mar=\"http://ANOTHER_LIBRARY\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></ram:FLOW>");
$header = $xml->addChild('Header');
$header->addChild('Source', $source);
$header->addChild('Time', $time);
$header->addChild('Environment', $env);
$header->addChild('Sequence', $sequence);
$data=$xml->addChild('Data');
$mar_oc_dc=$data->addChild('mar:OC_DC');
$dc_elements=$mar_oc_dc->addChild('DC_elements');
while($condition)
{
// some MySQL code here to extract unit_id and state
$unit=$dc_elements->addChild('Unit');
$unit_id=$unit->addChild('Unit_ID', $unit_id);
$state=$unit->addChild('State', $state);
}
$dom = new DOMDocument();
$dom->preserveWhiteSpace = FALSE;
$dom->formatOutput = TRUE;
$dom->loadXML($xml->asXML());
$handle = fopen("backup/" . $file_name . ".xml", "w");
fwrite($handle, $dom->saveXML());
fclose($handle);
?>
但结果与我的预期略有不同:
<?xml version="1.0" encoding="UTF-8"?>
<FLOW xmlns:ram=\"http://MY_LIBRARY\" xmlns:mar=\"http://ANOTHER_LIBRARY\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
<Header>
<Source>Application1</Source>
<Time>2014-11-12T12:46:39</Time>
<Environment>TEST</Environment>
<Sequence>537</Sequence>
</Header>
<Data>
<OC_DC>
<DC_elements>
<Unit>
<Unit_ID>089789</Unit_ID>
<State>active</State>
</Unit>
<Unit>
<Unit_ID>459008</Unit_ID>
<State>inactive</State>
</Unit>
</DC_elements>
</OC_DC>
</Data>
</FLOW>
如您所见, ram:FLOW 标记变为 FLOW , mar:OC_DC 标记变为 OC_DC 。 我查看了Stack Overflow和其他网站的解决方案,并没有设法找到一个。你能帮我一把吗?
提前谢谢。
答案 0 :(得分:1)
xmlns:*属性是命名空间定义(不是库)。该属性的值是一个唯一的字符串,用于标识元素所属的格式/标准。
属性定义唯一字符串的前缀,以便XML文档更小,更易读。
如果要在命名空间内创建元素(或属性),则必须提供命名空间。在SimpleXMlElement中,第三个参数是命名空间。
如果没有提供名称空间,它似乎会将元素添加到父节点的名称空间中。这意味着您必须为没有命名空间的任何元素提供空字符串。
$root = new SimpleXMlElement('<ram:FLOW xmlns:ram="http://MY_LIBRARY" xmlns:mar="http://ANOTHER_LIBRARY"/>');
$root->addChild('header', null, '');
$data = $root->addChild('data', null, '');
$data->addChild('mar:OC_DC', null, 'http://ANOTHER_LIBRARY');
echo $root->asXml();
输出:
<?xml version="1.0"?>
<ram:FLOW xmlns:ram="http://MY_LIBRARY" xmlns:mar="http://ANOTHER_LIBRARY">
<header xmlns=""/>
<data xmlns="">
<mar:OC_DC/>
</data>
</ram:FLOW>
我还没有找到避免空xmlns属性的方法。
DOM更明确。创建和追加逻辑是分开的。
const XMLNS_RAM = 'http://MY_LIBRARY';
const XMLNS_MAR = 'http://ANOTHER_LIBRARY';
$dom = new DOMDocument();
// appending an element with a namespace with define it if needed
$root = $dom->appendChild($dom->createElementNS(XMLNS_RAM, 'ram:FLOW'));
// setting the xmlns attribute explicit avoids the definition in descendant nodes
$root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:mar', XMLNS_MAR);
$root->appendChild($dom->createElement('header'));
$data = $root->appendChild($dom->createElement('data'));
$data->appendChild($dom->createElementNS(XMLNS_MAR, 'mar:OC_DC'));
$dom->formatOutput = true;
echo $dom->saveXml();
输出:
<?xml version="1.0"?>
<ram:FLOW xmlns:ram="http://MY_LIBRARY" xmlns:mar="http://ANOTHER_LIBRARY">
<header/>
<data>
<mar:OC_DC/>
</data>
</ram:FLOW>