dcarbone / xml-writer-plus
适用于PHP 5.4+的简单XML写入库
0.6.0
2021-01-01 00:20 UTC
Requires
- php: >=5.4.0
- ext-libxml: *
- ext-mbstring: *
- ext-xmlwriter: *
Requires (Dev)
- phpunit/phpunit: <6.0
Suggests
- ext-dom: Enable export to \DOMDocument
- ext-simplexml: Enable export to \SimpleXMLElement
README
适用于PHP 5.4+的简单XML写入库
该库的目的是为PHP内建的XMLWriter类提供一些附加功能。
在您的Composer应用中包含
添加
"dcarbone/xml-writer-plus" : "0.6.*"
到您的应用程序的composer.json
文件中。
在这里了解更多关于Composer的信息:https://getcomposer.org.cn/
基本用法
要开始创建您自己的XML文档
<?php use \DCarbone\XMLWriterPlus; // Initialize writer instance $xmlWriterPlus = new XMLWriterPlus(); // Start in-memory xml document $xmlWriterPlus->openMemory(); $xmlWriterPlus->startDocument(); // Write out a comment prior to any elements $xmlWriterPlus->writeComment('This is a comment and it contains superfluous information'); // Write root element (can be called anything you wish) $xmlWriterPlus->startElement('Root'); // Write a node value to the root element $xmlWriterPlus->text('Root element node value'); // Append a child element to the root element with it's own value // This method opens, writes value, and closes an element all in one go $xmlWriterPlus->writeElement('Child', 'Root element child element'); // Append a child element with some attributes in one go $xmlWriterPlus->writeElement('AttributedChild', 'some data', ['attr' => 'value!', 'ns:attr' => 'other value!']); // Insert a CDATA element $xmlWriterPlus->writeCDataElement('MyCData', '<div>This div won\'t confuse XML Parsers! <br></div>'); // Close root element $xmlWriterPlus->endElement(); // Make document immutable $xmlWriterPlus->endDocument(); // See our XML! echo htmlspecialchars($xmlWriterPlus->outputMemory());
上述代码将输出
<?xml version="1.0" encoding="UTF-8"?> <!--This is a comment and it contains superfluous information--><Root>Root element node value<Child>Root element child element</Child><AttributedChild attr="value!" ns:attr="other value!">some data</AttributedChild><MyCData><![CDATA[<div>This div won't confuse XML Parsers! <br></div>]]></MyCData></Root>
或者,更易于阅读的版本:
<?xml version="1.0" encoding="UTF-8"?> <!--This is a comment and it contains superfluous information--> <Root>Root element node value <Child>Root element child element</Child> <AttributedChild attr="value!" ns:attr="other value!">some data</AttributedChild> <MyCData><![CDATA[<div>This div won't confuse XML Parsers! <br></div>]]></MyCData> </Root>
命名空间
核心XMLWriter类的一个特性是能够为单个元素添加命名空间前缀和URI。这同样也是较为繁琐的一个特性,因为您必须为每个元素手动定义NS和URI。
为了解决这个问题,我添加了以下方法
/** * @param string $prefix * @param string $uri */ public function addNS($prefix, $uri); /** * @param string $prefix */ public function removeNS($prefix); /** * @param string $prefix * @return bool */ public function hasNSPrefix($prefix); /** * @param string $uri * @return bool */ public function hasNSUri($uri); /** * @return array */ public function getNSArray(); /** * @param array $nsArray */ public function setNSArray(array $nsArray); /** * @param string $prefix * @return string|bool */ public function getNSUriFromPrefix($prefix); /** * @param string $uri * @return mixed */ public function getNSPrefixFromUri($uri);
这些方法与内部的$prefix => $uri
关联数组进行交互。这些方法
/** * @param string $prefix * @param string $name * @param string|null $uri * @return bool */ public function startAttributeNS($prefix, $name, $uri = null); /** * @param string $prefix * @param string $name * @param string|null $uri * @param string|null $content * @return bool */ public function writeAttributeNS($prefix, $name, $uri = null, $content = null); /** * @param string $prefix * @param string $name * @param string|null $uri * @return bool */ public function startElementNS($prefix, $name, $uri = null); /** * @param string $prefix * @param string $name * @param string|null $uri * @param string|null $content * @return bool */ public function writeElementNS($prefix, $name, $uri = null, $content = null);
都已经修改为更新这个内部数组。所以如果您这样做
$xmlWriterPlus->startElementNS('pre', 'ElementName', 'http://my-special-prefix-uri.awesome'); $xmlWriterPlus->text('Test'); $xmlWriterPlus->endElement(); echo '<pre>'; var_export($xmlWriterPlus->getNSArray()); echo '</pre>';
您将看到
array ( 'pre' => 'http://my-special-prefix-uri.awesome', )
这可以使用
$xmlWriterPlus->writeElementNS('pre', 'ElementName', 'my awesome content');
将得到
<?xml version="1.0" encoding="UTF-8"?> <pre:ElementName xmlns:pre="http://my-special-prefix-uri.awesome">Test</pre:ElementName> <pre:ElementName xmlns:pre="http://my-special-prefix-uri.awesome">my awesome content</pre:ElementName>
如果您使用一个之前未定义的命名空间URI执行一个writeElement
调用,将使用NULL(不会输出xmlns属性)。
有趣的功能
假设您已经有一个打开的XMLWriterPlus实例以及已经构造好的数组,并且您希望将整个内容直接附加到XML输出中,而无需通过循环和手动执行操作。那么,尊贵的大人/女士/鱼,您完全能够做到!
$list = array( 'list value 1', 'list value 2', 'list value 3', ); $hash = array( 'HashKey1' => 'hash value 1', 'h:HashKey2' => 'hash value 2 with namespace', 'd:HashKey3' => 'hash value 3 with namespace', 'ChildElement1' => array( 'SubElement1' => 'sub element value 1', ), ); $xmlWriterPlus = new XMLWriterPlus(); $xmlWriterPlus->openMemory(); $xmlWriterPlus->startDocument(); $xmlWriterPlus->addNS('h', 'http://www.w3.org/TR/html4/'); $xmlWriterPlus->startElement('Root'); $xmlWriterPlus->appendList($list, 'MyList'); $xmlWriterPlus->appendHash($hash); $xmlWriterPlus->endElement(); $xmlWriterPlus->endDocument(); echo htmlspecialchars($xmlWriterPlus->outputMemory());
上述代码将输出
<?xml version="1.0" encoding="UTF-8"?> <Root><MyList>list value 1</MyList><MyList>list value 2</MyList><MyList>list value 3</MyList><HashKey1>hash value 1</HashKey1><h:HashKey2 xmlns:h="http://www.w3.org/TR/html4/">hash value 2 with namespace</h:HashKey2><d:HashKey3>hash value 3 with namespace</d:HashKey3><ChildElement1><SubElement1>sub element value 1</SubElement1></ChildElement1></Root>
扩展
<?xml version="1.0" encoding="UTF-8"?> <Root> <MyList>list value 1</MyList> <MyList>list value 2</MyList> <MyList>list value 3</MyList> <HashKey1>hash value 1</HashKey1> <h:HashKey2 xmlns:h="http://www.w3.org/TR/html4/">hash value 2 with namespace</h:HashKey2> <d:HashKey3>hash value 3 with namespace</d:HashKey3> <ChildElement1> <SubElement1>sub element value 1</SubElement1> </ChildElement1> </Root>
您还可以传递对象
$object = new \stdClass(); $object->ObjKey1 = 'obj value 1'; $object->ObjKey2 = 'obj value 2'; $object->ObjKey3 = array('ArrayKey1' => 'array value 1'); $xmlWriterPlus = new XMLWriterPlus(); $xmlWriterPlus->openMemory(); $xmlWriterPlus->startDocument(); $xmlWriterPlus->startElement('Root'); $xmlWriterPlus->appendHash($object); $xmlWriterPlus->endElement(); $xmlWriterPlus->endDocument(); echo htmlspecialchars($xmlWriterPlus->outputMemory());
上述代码将输出
<?xml version="1.0" encoding="UTF-8"?> <Root><ObjKey1>obj value 1</ObjKey1><ObjKey2>obj value 2</ObjKey2><ObjKey3><ArrayKey1>array value 1</ArrayKey1></ObjKey3></Root>
扩展
<?xml version="1.0" encoding="UTF-8"?> <Root> <ObjKey1>obj value 1</ObjKey1> <ObjKey2>obj value 2</ObjKey2> <ObjKey3> <ArrayKey1>array value 1</ArrayKey1> </ObjKey3> </Root>
哈希键说明
- 如上所示,您可以通过冒号(例如,'h:HashKey2')传递哈希键,XMLWriterPlus将自动创建一个命名空间元素。
- 只要类实现了PHP的迭代器接口,您就可以传递一个自定义类的对象实例
- 如果您希望在同一级别有多个相同名称的元素,您必须以如下方式传递一个数组
array('Parent' => array( array('Child' => 'Value' ), array('Child' => 'Value') ));