2017-06-27 45 views
3

我一直在努力工作幾個小時,試圖讓輸出XML匹配我給出的規範,而我找不到合適的代碼來完成它。我使用DOMDocument是因爲我讀到它比SimpleXML更靈活。帶命名空間的DOMDocument

所需的最終結果:

<?xml version="1.0" encoding="UTF-8"?> 
<retail xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <partnerid>XYZ</partnerid> 
    <customer xmlns:a="http://schemas.datacontract.org/2004/07/DealerTrack.DataContracts.CreditApp"> 
     <a:info> 
      <a:FirstName>Bob</a:FirstName> 
      <a:LastName>Hoskins</a:LastName> 
     </a:info> 
    </customer> 
    <refnum i:nil="true"/> 
</retail> 

...和我使用到那裏的代碼(略):

$node = new DOMDocument('1.0', 'UTF-8'); 
$root = $node->createElementNS('http://www.w3.org/2001/XMLSchema-instance', 'retail'); 
$root->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xmlns:i', 'test'); 

$capp = $node->appendChild($root); 

$cnode = $node->createElement("partnerid", 'XYZ'); 
$capp->appendChild($cnode); 

... ...這是不是讓我什麼我想要。我已經嘗試了至少一打createElementNS,setAttributeNS的組合,查看了幾個例子,並且找不到任何讓我接近我之後的東西。我已經可以在SimpleXML中做到這一點,但我想了解在這種情況下發生了什麼以及如何使用DOM。

+0

確定。 PHP不是我的語言,但我建議你簡化。從根元素開始。你把它放到http://www.w3.org/2001/XMLSchema-instance命名空間中,但這不是你想要的。根據你想要的結果,「retail」元素應該沒有名字空間。所以$ root = $ node-> createElement('retail');應該做。然後看看如何添加xmlns:i屬性,依此類推。一次解決一個問題。 – Alohci

回答

1

除了alex blex答案:對於根元素(並且只爲它),你也可以簡單地創建一個屬性名稱空間而不追加到根元素。

$dom = new DOMDocument('1.0', 'UTF-8'); 

$namespaceURIs = [ 
    'xmlns' => 'http://www.w3.org/2000/xmlns/', 
    'i' => 'http://www.w3.org/2001/XMLSchema-instance', 
    'a' => 'http://schemas.datacontract.org/2004/07/DealerTrack.DataContracts.CreditApp' 
]; 

$root = $dom->createElement('retail'); 
$dom->appendChild($root); 
$dom->createAttributeNS($namespaceURIs['i'], 'i:attr'); 
// note that you don't have to append it: `CreateAttributeNS` defines a namespace for 
// the entire document and will be automatically attached to the root element. 

$root->appendChild($dom->createElement('partnerid', 'XYZ')); 

$customer = $dom->createElement('customer'); 
$customer->setAttributeNS($namespaceURIs['xmlns'], 'xmlns:a', $namespaceURIs['a']); 
// `setAttributeNS` allows to define local namespaces, that's why it needs to be 
// attached to a particular element. 
$root->appendChild($customer); 

$info = $dom->createElementNS($namespaceURIs['a'], 'a:info'); 
$customer->appendChild($info); 
// etc. 

$dom->preserveWhiteSpace = false; 
$dom->formatOutput = true; 

echo $dom->saveXML(); 

demo

而且,隨意測試其他PHP的XML內置的API:XMLWriter

+0

不知道XMLWriter,能夠在15分鐘內完成DOM中幾小時無法完成的任務。我仍然無法圍繞命名空間 - 我理解他們的目的,但是在(例如)setAttributeNS中操縱他們讓我完全困惑。感謝大家的幫助! –

1

如果我明白問題是與retail元素。

$node = new DOMDocument('1.0', 'UTF-8'); 
$root = $node->createElement('retail'); 
$root->setAttributeNS(
    'http://www.w3.org/2000/xmlns/', 
    'xmlns:i', 
    'http://www.w3.org/2001/XMLSchema-instance' 
); 

$capp = $node->appendChild($root); 

$cnode = $node->createElement("partnerid", 'XYZ'); 
$capp->appendChild($cnode); 

應該給你預期的輸出。它很好地記錄在http://php.net/manual/en/domdocument.createelementns.php