2010-04-07 63 views
3

我熟悉DOMDocument :: importNode用於從其他文檔元素導入節點樹的方法。DOM:如何導入節點並給它們不同的名稱空間前綴

不過,我想知道是,如果我可以自動更改名稱空間前綴上的節點的樹,因爲我導入,也就是指定一個新的前綴,命名空間的所有節點。

說的節點,其現有的文件中,都有類似「名稱」,「身份」等名稱。將它們導入到我的新文檔中時,它們將與其他名稱空間一起使用,所以我希望它們顯示爲「nicnames:name」,「nicnames:identity」等。我希望能夠以編程方式更改此前綴,以便在另一個上下文中,我可以將它們導入爲例如「myprefix:name」,「myprefix:identity」,具體取決於它們導入到的文檔。

編輯:按我的回答解釋,我想通了,我實際上並不需要這樣做。我誤解了XML中的命名空間。

+0

經進一步調查事實證明,我實際上並不需要爲我工作的項目做到這一點。每當我改變命名空間時,只需使用適當的xmlns指標就足夠了。因此我不再需要這個答案;其他人可能會喜歡一個。 – thomasrutter 2010-04-08 13:02:37

回答

0

我發現我最好誤解XML命名空間。他們實際上比我想象的要好得多。

我倒認爲,一個單一的文件中使用的每個XML命名空間必須有一個不同的命名空間前綴。這不是真的。

即使沒有名稱空間前綴,只要在適當的位置包含xmlns屬性,並且xmlns屬性僅對該元素及其子元素有效,則可以在該文檔中使用不同的名稱空間,覆蓋該前綴的名稱空間樹高一點。

例如,有內另外一個命名空間,你沒有做的事:

<record xmlns="namespace1"> 
    <person:surname xmlns:person="namespace2">Smith</person:surname> 
</record> 

你可以做

<record xmlns="namespace1"> 
    <surname xmlns="namespace2">Smith</person> 
</record> 

命名空間前綴在某些情況下,一個很好的捷徑,但只要將一個文檔包含在另一個不同名稱空間內時不是必需的。

0

你可能需要編寫自己的導入代碼,然後。例如。

function importNS(DOMNode $target, DOMNode $source, $fnImportElement, $fnImportAttribute) { 
    switch($source->nodeType) { 
    case XML_ELEMENT_NODE: 
     // invoke the callback that creates the new DOMElement node 
     $newNode = $fnImportElement($target->ownerDocument, $source); 
     if (!is_null($newNode) && !is_null($source->attributes)) { 
     foreach($source->attributes as $attr) { 
      importNS($newNode, $attr, $fnImportElement, $fnImportAttribute); 
     } 
     } 
     break; 
    case XML_ATTRIBUTE_NODE: 
     // invoke the callback that creates the new DOMAttribute node 
     $newNode = $fnImportAttribute($target->ownerDocument, $source); 
     break; 
    default: 
     // flat copy 
     $newNode = $target->ownerDocument->importNode($source); 
    } 

    if (!is_null($newNode)) { 
    // import all child nodes 
    if (!is_null($source->childNodes)) { 
     foreach($source->childNodes as $c) { 
     importNS($newNode, $c, $fnImportElement, $fnImportAttribute); 
     } 
    } 
    $target->appendChild($newNode); 
    } 
} 

$target = new DOMDocument; 
$target->loadxml('<foo xmlns:myprefix="myprefixUri"></foo>'); 

$source = new DOMDocument; 
$source->loadxml('<a> 
    <b x="123">...</b> 
</a>'); 

$fnImportElement = function(DOMDocument $newOwnerDoc, DOMElement $e) { 
    return $newOwnerDoc->createElement('myprefix:'.$e->localName); 
}; 

$fnImportAttribute = function(DOMDocument $newOwnerDoc, DOMAttr $a) { 
    // could use namespace here, too.... 
    return $newOwnerDoc->createAttribute($a->name); 
}; 

importNS($target->documentElement, $source->documentElement, $fnImportElement, $fnImportAttribute); 
echo $target->savexml(); 

打印

<?xml version="1.0"?> 
<foo xmlns:myprefix="myprefixUri"><myprefix:a> 
    <myprefix:b x="123">...</myprefix:b> 
</myprefix:a></foo> 
相關問題