使用XMLWriter跟踪命名空间声明

3
我正在开发一个XML webservice(使用PHP!),为了做到“正确”,我想使用XMLWriter而不是仅仅将字符串拼接在一起然后希望一切顺利。
我正在使用-startElementNS和-writeElementNS在所有地方使用XML命名空间。问题是,每次使用这些函数时,都会写入新的命名空间声明。
虽然这是正确的语法,但有点多余。我想确保我的命名空间声明仅在文档上下文中首次使用时才被写入。
是否有一种简单的方法来使用XMLWriter解决这个问题,或者我必须子类化它并手动管理呢?
谢谢, Evert
2个回答

7

您可以在文档中的所需位置(例如顶层元素)一次写出命名空间:

$writer = new XMLWriter(); 
$writer->openURI('php://output'); 
$writer->startDocument('1.0'); 

$writer->startElement('sample');            
$writer->writeAttributeNS('xmlns','foo', null,'http://foo.org/ns/foo#');
$writer->writeAttributeNS('xmlns','bar', null, 'http://foo.org/ns/bar#');

$writer->writeElementNS('foo','quz', null,'stuff here');
$writer->writeElementNS('bar','quz', null,'stuff there');

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

这应该最终变成类似于这样的内容。
<?xml version="1.0"?>
<sample xmlns:foo="http://foo.org/ns/foo#" xmlns:bar="http://foo.org/ns/bar#">
 <foo:quz>stuff here</foo:quz>
 <bar:quz>stuff there</bar:quz>
</sample>

有时候,xmlwriter并不能跟踪这些声明,这会让你写出无效的xml,有些烦人。同样让人不爽的是,即使属性可以为空,它仍然是必须的,而且它是第三个参数而不是最后一个。

$2c, *-pike


6

You can pass NULL as the uri parameter.

<?php
$w = new XMLWriter;
$w->openMemory();
$w->setIndent(true);
$w->startElementNS('foo', 'bar', '<a rel="noreferrer" href="http://whatever/foo">http://whatever/foo</a>');
$w->startElementNS('foo', 'baz', null);
$w->endElement();
$w->endElement();
echo $w->outputMemory();
prints
<foo:bar xmlns:foo="http://whatever/foo">
 <foo:baz/>
</foo:bar>


不完全是我想要的。在你的例子中,“bar”和“baz”元素可能由完全不同的对象和方法实现,它们并不总是彼此知晓。我__始终__想要指定命名空间,但我希望它只在第一次渲染时呈现。 - Evert
我在php/xmlwriter或libxml/xmlwriter中没有找到任何支持。你可能需要自己跟踪这个问题。 - VolkerK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接