簡體   English   中英

從子元素 XML PHP 中刪除命名空間

[英]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
  • this(及其所有子元素)中的前綴是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM