我使用PHP实现来修改内置DOM文档,特别是ODS电子表格中的content.xml文件。本文档大量使用名称空间(根元素中声明了35个不同的名称空间)。
我试图使用浅层table-cell将一个cloneNode()元素复制到一个新行,但是结果与原来的不完全相同:
<?xml version="1.0" encoding="UTF-8"?>
<office:document-content
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
[... snip 32 ...]>
<!-- original -->
<table:table-cell table:style-name="ce5"
office:value-type="string"
calcext:value-type="string">
<!-- cloned -->
<table:table-cell xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
table:style-name="ce5"
office:value-type="string"
calcext:value-type="string">虽然这在语义上是相似的,但它可能会在较大的电子表格中造成很大的膨胀(即使XML是压缩在磁盘上的)。
有解决办法吗?
首先,使用非命名空间感知方法并简单地复制属性(包括前缀和标记名)的天真方法似乎是可行的:
$clone = $doc->createElement($ele->tagName);
foreach ($ele->attributes as $att) {
$clone->setAttribute($att->nodeName, $att->value);
}生成的XML看起来与预期的完全相同。但是,当克隆元素再次被操作时:
$clone->setAttributeNS($officeNS, "office:value-type", "string");结果有两个相同的属性名:
<table:table-cell xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
table:style-name="ce5"
office:value-type="string"
calcext:value-type="string"
office:value-type="string"
office:string-value="">这使得文档无效。通常,我发现混合命名空间和非命名空间的方法调用是不可行的。
发布于 2016-11-11 15:14:40
下面是一个libxml常量,允许在加载时优化名称空间:
$xml = <<<'XML'
<f:foo xmlns:f="urn:foo">
<f:foo>
<f:foo xmlns:f="urn:foo">
</f:foo>
</f:foo>
</f:foo>
XML;
$document = new DOMDocument();
$document->loadXml($xml, LIBXML_NSCLEAN);
echo $document->saveXml();输出:
<?xml version="1.0"?>
<f:foo xmlns:f="urn:foo">
<f:foo>
<f:foo>
</f:foo>
</f:foo>
</f:foo>这主要是可行的,但如果同一文档中的不同名称空间使用相同的前缀,则会得到一些无效的结果。
FluentDOM库包含此作业的优化器。它还允许您更改/定义前缀。
https://stackoverflow.com/questions/40538406
复制相似问题