s9e / sweetdom
专注于XSLT 1.0模板操作的DOM API语法糖。
Requires
- php: ^8.1
- ext-dom: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.52
- phpunit/phpunit: ^10.0
- s9e/repdoc: dev-wip
This package is auto-updated.
Last update: 2024-08-27 02:03:14 UTC
README
s9e\SweetDOM是一个库,它扩展了PHP的DOM扩展,使DOM操作更简单,特别关注XSLT 1.0模板。它为最常用的DOM操作添加了语法糖,提高了跨PHP版本的兼容性,并实现了某些新方法的polyfills。
安装
composer require s9e/sweetdom
API
s9e\SweetDOM\Document
s9e\SweetDOM\Document
类扩展了DOMDocument
,并提供了快速访问DOMXPath的evaluate
和query
方法。`firstOf`方法评估XPath查询并返回列表中的第一个节点,如果列表为空,则返回`null`。
mixed evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true) ?DOMNode firstOf(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true) DOMNodeList query(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true)
s9e\SweetDOM\Document
类有一个`$nodeCreator`属性,它提供了一组方法来创建元素,特别关注模板中常用的XSL元素。有关完整内容,请参阅s9e\SweetDOM\NodeCreator
。
Comment createComment(string $data) Element createElement(string $nodeName, string $textContent = '') Element createElementNS(?string $namespace, string $nodeName, string $textContent = '') Element createXslApplyTemplates(string $select = null, string $mode = null) Element createXslAttribute(string $name, string $textContent = '', string $namespace = null) Element createXslChoose() Element createXslComment(string $textContent = '') Element createXslCopyOf(string $select) Element createXslElement(string $name, string $namespace = null, string $useAttributeSets = null) Element createXslIf(string $test, string $textContent = '') Element createXslOtherwise(string $textContent = '') Element createXslText(string $textContent = '', string $disableOutputEscaping = null) Element createXslValueOf(string $select, string $disableOutputEscaping = null) Element createXslVariable(string $name, string $select = null) Element createXslWhen(string $test, string $textContent = '')
s9e\SweetDOM\Element
s9e\SweetDOM\Element
类扩展了DOMElement
,并提供了同时创建节点并将其相对于元素插入的一组魔法方法。对于来自s9e\SweetDOM\NodeCreator
类的每个方法,在s9e\SweetDOM\Element
上存在五个相应的方法。
例如,来自s9e\SweetDOM\NodeCreator
的`createXslText`方法在s9e\SweetDOM\Element
中变为`afterXslText`、`appendXslText`、`beforeXslText`、`prependXslText`和`replaceWithXslText`方法。每个方法都创建一个节点,执行DOM操作,然后返回该节点。以下示例说明了每个`xsl:text`元素相对于创建它们的`span`元素的位置插入,然后替换`br`元素。
$xsl = '<xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <p><span><br/></span></p> </xsl:template>'; $dom = new s9e\SweetDOM\Document; $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $dom->loadXML($xsl); $span = $dom->firstOf('//span'); $methods = ['afterXslText', 'appendXslText', 'beforeXslText', 'prependXslText']; foreach ($methods as $methodName) { $span->$methodName($methodName); } $dom->firstOf('//br')->replaceWithXslText('replaceWithXslText'); echo $dom->saveXML($dom->documentElement);
<xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <p> <xsl:text>beforeXslText</xsl:text> <span> <xsl:text>prependXslText</xsl:text> <xsl:text>replaceWithXslText</xsl:text> <xsl:text>appendXslText</xsl:text> </span> <xsl:text>afterXslText</xsl:text> </p> </xsl:template>
XPath方法在元素级别也可用,并使用元素本身作为上下文节点。
$dom = new s9e\SweetDOM\Document; $dom->loadXML('<x id="1"><x id="2"/></x>'); var_dump($dom->firstOf('//x')->getAttribute('id')); var_dump($dom->firstOf('//x')->firstOf('x')->getAttribute('id'));
string(1) "1"
string(1) "2"
可以使用以下API轻松创建和将元素相对于上下文节点添加。
Element afterElement(string $nodeName, string $textContent = '') Element appendElement(string $nodeName, string $textContent = '') Element beforeElement(string $nodeName, string $textContent = '') Element prependElement(string $nodeName, string $textContent = '')
$dom = new s9e\SweetDOM\Document; $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $dom->loadXML('<p><span><br/></span></p>'); $span = $dom->firstOf('//span'); $methods = ['afterElement', 'appendElement', 'beforeElement', 'prependElement']; foreach ($methods as $methodName) { $span->$methodName('i', $methodName); } echo $dom->saveXML($dom->documentElement);
<p> <i>beforeElement</i> <span> <i>prependElement</i> <br/> <i>appendElement</i> </span> <i>afterElement</i> </p>
文档片段可用于批量操作或在DOM中插入XML。
$dom = new s9e\SweetDOM\Document; $dom->loadXML('<x/>'); $x = $dom->firstOf('//x'); $x->appendDocumentFragment( // The callback will be executed before the fragment is appended fn($fragment) => $fragment->appendXML('<y/><z/>') ); echo $dom->saveXML($x);
<x><y/><z/></x>
其他扩展节点
以下DOM节点自动扩展并增加了XPath方法以及节点类型支持的任何魔法方法,通常通过DOMChildNode
和DOMParentNode
接口实现。
s9e\SweetDOM\Attr
扩展了DOMAttr
s9e\SweetDOM\CdataSection
扩展了DOMCdataSection
s9e\SweetDOM\Comment
扩展了DOMComment
s9e\SweetDOM\DocumentFragment
扩展了DOMDocumentFragment
s9e\SweetDOM\Element
扩展了DOMElement
s9e\SweetDOM\Text
扩展了DOMText
与较旧和未来的PHP版本的前后兼容性
为了提高与较旧版本的PHP以及PHP的未来的版本的兼容性,此库根据PHP版本使用不同的类集来实现节点类型。基本类在上面的s9e\SweetDOM
命名空间中列出,并且在使用时应该只使用这些类来检查类类型。
与旧版本PHP的向后兼容性
为PHP < 8.3版本提供以下方法的polyfills
Node::isEqualNode
ParentNode::insertAdjacentElement
ParentNode::insertAdjacentText
ParentNode::replaceChildren
在PHP版本低于8.1.23,以及从8.2.0到8.2.9的版本中,以下方法被模拟
ChildNode::after
ChildNode::before
ChildNode::replaceWith
ParentNode::append
ParentNode::prepend
与未来版本PHP的前向兼容性
以下方法已被修改,以匹配PHP 8.3对断开连接的节点(无父节点的节点)的行为,并与DOM规范保持一致。
ChildNode::after
ChildNode::before
ChildNode::replaceWith