[英]Remove Namespace from child Element XML PHP
我正在嘗試使用simpleXML創建一個 xml 文件。
這是我需要的輸出:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0" version="2.0">
<channel>
<title>MY XML</title>
<item>
<g:id>123</g:id>
<title>abc</title>
<g:type>vertical</g:type>
<g:price>0.00</g:price>
</item>
</channel>
</rss>
但這就是我在向 addChild 函數添加第三個參數時得到的結果:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0" version="2.0">
<channel>
<title>MY XML</title>
<item>
<g:id xmlns:g="id">123</g:id>
<title>abc</title>
<g:type xmlns:g="type">vertical</g:type>
<g:price xmlns:g="price">0.00</g:price>
</item>
</channel>
</rss>
我試圖像這樣將第三個參數留空: $xml->addChild('g:id', 123, '');
但它仍然像這樣添加它: <g:id xmlns:g="">123</g:id>
有任何想法嗎?
SimpleXMLElement::addChild
在其第三個參數中需要名稱空間(如果不是默認名稱)。
如果命名空間尚未注冊,則會添加。 這就是您在結果中看到的。
但是,您想在特定的現有命名空間中添加子元素,即http://base.google.com/ns/1.0
(它看起來像一個 URL,但就 XML 而言它只是一個字符串)。
例子:
$namespace = 'http://base.google.com/ns/1.0';
$root->channel->item->addChild('id', '456', $namespace);
# adds child <g:id>456</g:id>
這就是您想要的:在http://base.google.com/ns/1.0
命名空間中添加id
元素。
這里的命名空間縮寫為g
,即所謂的前綴 ( g:...
)。 您可以想象元素名稱是{http://base.google.com/ns/1.0}id
( "Clark notation" )。
查看第一個(根/文檔)元素,您可以看到哪個前綴代表哪個命名空間:
<rss xmlns:g="http://base.google.com/ns/1.0"
xmlns:c="http://base.google.com/cns/1.0" version="2.0">
這就是為什么在添加和告知正確的命名空間時僅使用id
作為元素名稱,它會以g
前綴插入。
但是,當您在名稱中顯式指定前綴添加子元素並提供(新)命名空間時,該元素前綴的命名空間將與添加的子元素一起使用,因為您告訴 SimpleXML 這樣做(在您的情況下是偶然/錯誤不是有意的,但這只是為了解釋發生了什么)。
<g:id xmlns:g="id">123</g:id>
id
; 帶前綴: g:id
; 帶有命名空間: {id}id
id
g
這就是為什么您需要知道您添加的子元素的名稱空間,因此您需要知道(長)名稱空間名稱: http://base.google.com/ns/1.0
://base.google.com/ns/1.0。
要找到它,請查找具有xmlns:<prefix>
屬性的元素,然后查看值:
<rss xmlns:g="http://base.google.com/ns/1.0" ...>
^ \___________________________/
| namespace
prefix g is ---/
當您使用該名稱空間調用addChild()
時,SimpleXML 將自動選擇現有前綴(此處為: g
)。
但是,如果該子元素是具有該(文檔的新)命名空間的第一個元素,它將像您的情況一樣使用xmlns
屬性添加(所有以xml
開頭的屬性(不區分大小寫)都是 XML 中的保留屬性名稱,對於元素名稱):
<g:price xmlns:g="price">0.00</g:price>
前綴“g”是該“price”元素的命名空間“price”(以及它的所有子元素,如果有的話,直到另一個子元素重新定義前綴的命名空間)。
如果您現在(在代碼中)顯式查找前綴是哪個名稱空間,您可以通過調用SimpleXMLElement::getNamespaces
來獲取關聯數組:
$namespace = $root->getNamespaces(true)['g'];
然而,使用真正的命名空間名稱要好得多,因為前綴可以任意變化,並且在命名空間名稱保持穩定時可能會發生變化。 編寫的代碼也更少:
$namespace = 'http://base.google.com/ns/1.0';
$root->channel->item->addChild('id', '456', $namespace);
您只需創建屬性並使用 simpleXML 設置值。
$xml = simplexml_load_string($xmlString);
$xml->channel->item->{'g:id'} = '123';
這將附加
<g:id>123</g:id>
到項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.