dcarbone/xml-writer-plus

适用于PHP 5.4+的简单XML写入库

0.6.0 2021-01-01 00:20 UTC

This package is auto-updated.

Last update: 2024-08-28 17:03:14 UTC


README

Build Status

适用于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') ));