微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 如何提取DOM childNodes或重命名元素而不使用迭代?

$xml = '<p><a>1</a><b><c>1</c></b></p>';
$dom = new DomDocument;
$dom->loadXML($xml);
$p   = $dom->childNodes->item(0);
echo $dom->saveXML($p);

以上将打印回来

<p>
  <a>1</a>
  <b><c>1</c></b>
</p>

假设需要将p节点/ eleemnt替换为new_p
什么是理想的方式,除了像下面的循环? (以下是可行的)

$fragment = '';
foreach ($p->childNodes as $a)
{
  $fragment .= $dom->saveXML($a);
}

$new_doc = new DomDocument;
$new_doc->loadXML('<new_node/>');
$f = $new_doc->createDocumentFragment();
$f->appendXML($fragment);
$new_doc->documentElement->appendChild($f);
echo $new_doc->saveXML();

预期成绩

<new_node><a>1</a><b><c>1</c></b></new_node>

解决方法:

正如Mark已经指出的那样,使用XSLT操作XML是最简单的.而且你不必编写任何循环,思考是由你选择的XSLT处理器完成的.

一个简单的XSLT方法

以下是XSLT的外观(对于某些教程,Google为“Identity transform XSLT”).

基础很简单:这种类型的XSLT转换按原样复制所有内容,除非在特定规则(XSLT中的模板匹配)中指定了异常(在本例中为< p>元素).注意:嵌入p标签的深度并不重要,这使其成为转换XML的理想选择.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- identity transform -->
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- rename "p" with "new_p", copy everything inside p -->
    <xsl:template match="p">
        <new_p>
            <xsl:apply-templates select="@* | node()"/>
         </new_p>
    </xsl:template>

</xsl:stylesheet>

PHP调用XSLT

这是相对简单的,因为PHP有​​一个内置的XSL模块.这是你如何做到的(here’s more information):

// create an XSLT processor and load the stylesheet as a DOM 
$xproc = new XsltProcessor();
$xslt = new DomDocument;
$xslt->load('yourstylesheet.xslt');    // this contains the code from above
$xproc->importStylesheet($xslt);


// your DOM or the source XML (copied from your question)
$xml = '<p><a>1</a><b><c>1</c></b></p>';
$dom = new DomDocument;
$dom->loadXML($xml);

// do the transformation
if ($xml_output = $xproc->transformToXML($dom)) {
    echo $xml_output;
} else {
    trigger_error('Oops, XSLT transformation Failed!', E_USER_ERROR);
} 

输出与预期一致(可以使用< xsl:output indent =“yes”/>设置可选缩进:

<new_p>
    <a>1</a>
    <b><c>1</c></b>
</new_p>

如您所见:没有循环或迭代;)

PS:XSLT是一种广泛采用且稳定的标准.您不必担心正确转义,解析CDATA部分或实体的问题,因为XSLT保证输出是有效的XML.与手工操作相比,这节省了许多麻烦.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐