【发布时间】:2016-11-10 22:51:52
【问题描述】:
我正在使用 PHP 的 built-in DOM 实现来修改 XML 文档,特别是 ODS 电子表格中的 content.xml 文件。本文档大量使用了命名空间(在根元素中声明了 35 个不同的命名空间)。
我正在尝试使用浅cloneNode() 将table-cell 元素复制到新行,但结果与原始结果不完全相同:
<?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="">
这会使文档无效。一般来说,我发现混合命名空间和非命名空间方法调用是不切实际的。
【问题讨论】:
标签: php xml dom xml-namespaces