php - 使用 PHP 为 XML 标记设置命名空间

标签 php xml dom namespaces simplexml

我想创建一个具有非常特定格式的 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:流量标签变成了流量 ,以及 mar:OC_DC 标签变成了 OC_DC .
我在 Stack Overflow 和其他网站上寻找解决方案,但没有找到。你能帮我处理一下吗?

先感谢您。

最佳答案

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>

关于php - 使用 PHP 为 XML 标记设置命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26888064/

相关文章:

javascript - 从Javascript中的当前事件获取最近的祖先

php - 如何使用javascript检查是否选择了文件?

php - 从 jQuery 代码中的 WordPress 短代码获取 URL

xml - 在使用 FOP 生成的 PDF 中显示换行符

xml - 将不同源位置的 xml 文档图像复制到单个输出目录中

javascript - 通过 ClassName 在 DOM 中查找引用节点

javascript - 使用 jQuery 创建一个元素并设置其属性

php - UNIX 时间戳(0) : Europe/London returns UTC+1

php - SQL注入(inject)测试-mysql_query

c# - Stream 和 XmlTextwriter...请求未正确接收