我正在嘗試使用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>
有任何想法嗎?
uj5u.com熱心網友回復:
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>
這就是你想要的:id在命名空間中添加元素http://base.google.com/ns/1.0。
這里命名空間縮寫為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 - this(及其所有子元素)中的前綴是
g
這就是為什么您需要知道您添加的子元素的名稱空間,因此您需要知道(長)名稱空間名稱:http://base.google.com/ns/1.0。
要找到它,請查找具有該xmlns:<prefix>屬性的元素,然后查看值:
<rss xmlns:g="http://base.google.com/ns/1.0" ...>
^ \___________________________/
| namespace
prefix g is ---/
當您使用該名稱空間呼叫時, SimpleXML 將自動選擇addChild()現有前綴(此處為:)。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);
uj5u.com熱心網友回復:
您只需創建屬性并使用 simpleXML 設定值。
$xml = simplexml_load_string($xmlString);
$xml->channel->item->{'g:id'} = '123';
這將附加
<g:id>123</g:id>
到專案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/495839.html
