php - How to keep DOMNode::cloneNode() from inserting redundant namespaces? -
i'm using php's built-in dom implementation modify xml document, content.xml file in ods spreadsheet. document makes heavy use of namespaces (35 different namespaces declared in root element).
i'm trying copy table-cell element new row using shallow clonenode(), result not identical original:
<?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"> while semantically similar, can cause major bloat in larger spreadsheets (even though xml zipped on disk).
is there solution this?
the naive approach of using non-namespace aware methods, , copying attributes (including prefix , tag name), appears works, @ first:
$clone = $doc->createelement($ele->tagname); foreach ($ele->attributes $att) { $clone->setattribute($att->nodename, $att->value); } the resulting xml looks intended. when cloned element manipulated again:
$clone->setattributens($officens, "office:value-type", "string"); the result has two identical attribute names:
<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=""> which makes document invalid. in general, found unpracticable mix namespaced , non-namespaced method calls.
here libxml constant allows optimize namespaces on loading:
$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(); output:
<?xml version="1.0"?> <f:foo xmlns:f="urn:foo"> <f:foo> <f:foo> </f:foo> </f:foo> </f:foo> this works mostly, got invalid results if same prefix used different namespaces in same document.
the fluentdom library contains optimizer job. allows change/define prefixes, too.
Comments
Post a Comment