josemmo / uxml
一个简洁且语法简洁的XML操作库
Requires
- php: >=7.1
- lib-libxml: *
Requires (Dev)
README
UXML是一个极简的PHP库,可以轻松操作XML文档,同时将开销降到最低。
它仅包含一个类,该类在底层使用PHP内置的DOMElement
和DOMDocument
类。
安装
使用Composer
composer require josemmo/uxml
不使用Composer
从GitHub仓库下载源文件
git clone https://github.com/josemmo/uxml.git
在您的应用程序中使用UXML类
use UXML\UXML; require_once __DIR__ . "/uxml/src/UXML.php";
常见问题解答
为什么使用这个而不是 sabre/xml 或 FluidXML?
这两个选项都很好,如果它们适合您的项目,您绝对应该使用它们!然而,在我的情况下,我需要更轻量级的解决方案,以在LibXML的DOM之上提供替代语法。
UXML与DOMElement
兼容吗?
是的,确实如此!您可以从一个UXML
对象中获取原始的DOMElement
实例,反之亦然。
我想让UXML做“X”。你能实现它吗?
这个项目的主要目标不是实现XML规范中所有可能的行为,您可以使用DOM或SimpleXML库来做到这一点。
用法
创建新文档
UXML不区分XML文档(DOMDocument
)和元素(DOMElement
)。相反,您可以创建一个新文档如下
$xml = \UXML\UXML::newInstance('RootTagName');
您也可以包装一个已经存在的DOMElement
$domElement = new DOMElement('TagName'); $xml = \UXML\UXML::fromElement($domElement);
从源加载XML文档
通过加载XML字符串,UXML将返回文档树根元素
$source = <<<XML <fruits> <fruit>Banana</fruit> <fruit>Apple</fruit> <fruit>Tomato</fruit> </fruits> XML; $xml = \UXML\UXML::fromString($source);
向节点添加元素
在添加元素时,UXML将返回对新创建元素的引用
$xml = \UXML\UXML::newInstance('Parent'); $child = $xml->add('Child'); echo $child; // <Child /> echo $xml; // <Parent><Child /></Parent>
您也可以定义一个值
$child = $xml->add('Child', 'Hello World!'); echo $child; // <Child>Hello World!</Child>
甚至属性或命名空间
$feed = \UXML\UXML::newInstance('feed', null, [ 'xmlns' => 'http://www.w3.org/2005/Atom' ]); echo $feed; // <feed xmlns="http://www.w3.org/2005/Atom" /> $link = $feed->add('link', 'Wow!', [ 'href' => 'https://www.example.com' ]); echo $link; // <link href="https://www.example.com">Wow!</link>
元素链
因为每次元素插入都会返回对新元素的引用,所以您可以将多个此类调用链式调用以创建树
$xml = \UXML\UXML::newInstance('people'); $xml->add('person')->add('name', 'Jane Doe'); echo $xml; // <people> // <person> // <name>Jane Doe</name> // </person> // </people>
导出XML源
除了将UXML
对象转换为字符串外,还有一个方法可以导出元素及其子元素的XML源
$xml->asXML();
默认情况下,导出的字符串包含XML声明(除非将UXML
实例转换为字符串)。
查找XML元素
UXML允许您使用XPath 1.0查询从文档中获取特定元素
$xml = \UXML\UXML::newInstance('person'); $xml->add('name', 'Jane'); $xml->add('surname', 'Doe'); $xml->add('color', 'green', ['hex' => '#0f0']); echo $xml->get('*[@hex]'); // <color hex="#0f0">green</color> var_dump($xml->get('birthday')); // NULL
甚至多个元素
$xml = \UXML\UXML::fromString('<a><b>1</b><b>2</b><b>3</b></a>'); foreach ($xml->getAll('b') as $elem) { echo "Element says: " . $elem->asText() . "\n"; }
注意,所有XPath查询都是相对于当前元素进行的
$source = <<<XML <movie> <name>Inception</name> <year>2010</year> <director> <name>Christopher</name> <surname>Nolan</surname> <year>1970</year> </director> </movie> XML; $xml = \UXML\UXML::fromString($source); echo $xml->get('director/year'); // <year>1970</year> echo $xml->get('director')->get('year'); // <year>1970</year> echo $xml->get('year'); // <year>2010</year> echo $xml->get('director')->get('//year'); // <year>2010</year>
删除XML元素
可以通过在元素上调用remove()
方法从XML树中删除元素。元素被删除后,它变得不可用
$source = <<<XML <project> <public> <name>Alpha</name> </public> <confidential> <budget>1,000,000 USD</budget> </confidential> </project> XML; $xml = \UXML\UXML::fromString($source); $xml->get('confidential')->remove(); echo $xml; // <project><public><name>Alpha</name></public></project>
命名空间
命名空间的分配方式与其他属性相同
$xml->add('TagName', null, [ 'xmlns' => 'https://example.com', 'xmlns:abc' => 'urn:abc', 'attribute' => 'value' ])->add('abc:Child', 'Name'); echo $xml; // <TagName xmlns="https://example.com" // xmlns:abc="urn:abc" // attribute="value"> // <abc:Child>Name</abc:Child> // </TagName>
然而,在查询元素时,文档中定义的前缀可能不是您期望的
$xml = \UXML\UXML::fromString('<a xmlns:ns="urn:abc"><ns:b /></a>'); echo $xml->get('ns:b'); // <ns:b /> echo $xml->get('abc:b'); // Is NULL as the prefix does not exist
为了解决这个问题,您可以在XPath查询中使用Clark表示法
echo $xml->get('{urn:abc}b'); // <ns:b />
高级XML操作
对于此库范围之外的其他文档操作,您始终可以与DOMElement
实例交互
$xml = \UXML\UXML::newInstance('Test'); $xml->element(); // Returns a [DOMElement] object