我正在开发一个模板引擎,已经从正则表达式驱动迁移到DOM驱动。但是,无论何时我创建DomDocumentFragment
来临时封装文档的某些部分,都会将命名空间属性添加到片段中的每个节点。由于给定文档的默认命名空间99%的时间都是XHTML,因此它添加了XHTML命名空间声明。
作为默认命名空间,这看起来毫无结果,并且最终在渲染时将剥离任何其他命名空间中的节点。
除了迭代删除命名空间属性之外,还有一些方法可以防止这种情况发生吗?这很成问题,因为这可能会大大增加渲染时间文件大小,因为给定文档的大部分可能存储在片段中。
我尝试过$doc->normalizeDocument()
,但正如我所说,它没有做任何事情。
答案 0 :(得分:2)
取决于您对额外计算的容忍度,以解决主要是美学问题(我说主要是,因为我同意它确实占用了额外的空间,但除此之外没关系),您可以通过XSL身份模板运行整个XML。
我必须编写一个功能齐全的示例来确保该技术确实有效:
<?php
$xmlIdentityTemplate = '<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>';
$xmlExample = '<?xml version="1.0"?>
<ns1:root xmlns:ns1="urn:ns1" xmlns:ns2="urn:ns2">
<ns1:node1>
<ns2:subnode1 xmlns:ns2="urn:ns2">node1 subnode1</ns2:subnode1>
<ns2:subnode2 xmlns:ns2="urn:ns2">node1 subnode2</ns2:subnode2>
<ns2:subnode3 xmlns:ns2="urn:ns2">node1 subnode3</ns2:subnode3>
<ns2:subnode4 xmlns:ns2="urn:ns2">node1 subnode4</ns2:subnode4>
</ns1:node1>
<ns1:node2>
<ns2:subnode1 xmlns:ns2="urn:ns2">node2 subnode1</ns2:subnode1>
<ns2:subnode2 xmlns:ns2="urn:ns2">node2 subnode2</ns2:subnode2>
<ns2:subnode3 xmlns:ns2="urn:ns2">node2 subnode3</ns2:subnode3>
<ns2:subnode4 xmlns:ns2="urn:ns2">node2 subnode4</ns2:subnode4>
</ns1:node2>
</ns1:root>';
$originalDocument = new DOMDocument();
$originalDocument->loadXML($xmlExample);
$xslDocument = new DOMDocument();
$xslDocument->loadXML($xmlIdentityTemplate);
$processor = new XSLTProcessor();
$processor->importStyleSheet($xslDocument);
$resultDocument = $processor->transformToDoc($originalDocument);
echo "<h1>Before:</h1>";
echo "<pre>" . htmlentities($originalDocument->saveXML()) . "</pre>";
echo "<h1>After:</h1>";
echo "<pre>" . htmlentities($resultDocument->saveXML()) . "</pre>";