XMLWriter看起来很破碎,因为它产生的命名空间声明 导致实例格式不正确。
例如:
$writer = new XMLWriter();
$writer->openUri( 'php://output' );
$writer->startIndent( true );
$writer->setIndentString ( "\t" );
$writer->startDocument( '1.0', 'UTF-8' );
$writer->startElement( 'root' );
$writer->writeAttributeNs( 'xmlns', 'bar', 'http://www.w3.org/2000/xmlns/', 'http://example.com' );
$writer->startElementNs( 'bar', 'baz', null );
$writer->endElement();
产生
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:bar="http://example.com" xmlns:xmlns="http://www.w3.org/2000/xmlns/">
<bar:baz/>
</root>
注意xmlns:xmlns="http://www.w3.org/2000/xmlns/"
,其中:
无论我做什么,如果我创建任何命名空间声明,那么XMLWriter会输出这个非法的命名空间声明(除了我希望它输出的命名空间声明)。
我错过了什么?因为,这会使XMLWriter无法使用。
编辑:如果重要,我使用的是PHP 5.4.16和libxml2 2.7.8。
答案 0 :(得分:0)
我找到了一个解决方法:创建名称空间decls,只需使用:
$writer->writeAttribute( 'xmlns:prefix', 'http://example.com' );
所以,我认为问题只是缺乏PHP手册中的文档。
BTW,我的问题中的代码示例是我实际编写的代码的简化,它使用XMLReader&amp; amp;来实现对实例的简单转换。 XMLWriter,ala:$reader = new XMLReader();
$reader->open( $file );
$writer = new XMLWriter();
$writer->openUri( "{$file}-xformed.xml" );
$writer->setIndent( true );
$writer->setIndentString( "\t" );
$writer->startDocument( '1.0', 'UTF-8' );
while ( $reader->read() ) {
switch ( $reader->nodeType ) {
case XMLReader::ELEMENT:
if ( '' === $reader->namespaceURI ) {
$writer->startElement( $reader->localName );
}
else {
$writer->startElementNS( $reader->prefix, $reader->localName, $reader->namespaceURI );
}
if ( $reader->hasAttributes ) {
while ( $reader->moveToNextAttribute() ) {
if ( '' === $reader->namespaceURI ) {
$writer->writeAttribute( $reader->name, $reader->value );
}
else {
// this stmt was causing the illegal namespace decls
// even tho there is nothing wrong with the code :-(
$writer->writeAttributeNS( $reader->prefix, $reader->localName, $reader->namespaceURI, $reader->value );
}
}
}
break;
// other case stmts for other node types
}
}
所以,我刚刚更换了&#34;属性循环&#34;用:
if ( $reader->hasAttributes ) {
while ( $reader->moveToNextAttribute() ) {
if ( in_array( $reader->namespaceURI, array( '', 'http://www.w3.org/2000/xmlns/' ) ) {
// create an attribute in the empty namespace or a namespace decl
$writer->writeAttribute( $reader->name, $reader->value );
}
else {
// create a namespace-qualified attribute
$writer->writeAttributeNS( $reader->prefix, $reader->localName, $reader->namespaceURI, $reader->value );
}
}
}