2011-07-08 17 views
3

怒っているので、私はほとんど話すことができません。私はSimpleXMLでRSSフィードを組み立てましたが、今は名前空間を使用しています。しかし、出力時にルートノードにxmlns:xmlns = ""を宣言しようと常に試みています。私はそのようなことはしませんが。SimpleXMLにはxmlns:xmlns = ""という宣言があります。削除する方法はありません

それは

$rssXML->addAttribute("version", '2.0'); 
$rssXML->addAttribute("xmlns:media", "http://search.yahoo.com/mrss/", ''); 
$rssXML->addAttribute("xmlns:dcterms", "http://purl.org/dc/terms/", ''); 

で始まり、この後、私は行います -

header("Content-Type: application/rss+xml"); 

echo $syndicationXML->asXML(); 

それでも、出力: -

<?xml version="1.0"?> 
<rss xmlns:xmlns="" version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/"><channel>... 

私はすべてこの名前空間宣言を理解していません。どうしたの?

答えて

6

SimpleXMLの問題点は、addAttributeという名前の関数が名前空間ではなく属性を追加するということです。あなたの望むように見えますが、それを使用する方法ではありません。

これは、特定の名前空間(3番目のパラメータとして指定)の一部である値を追加するためのもので、名前空間自体を追加するものではありません。 xmlns:xmlnsで終わる理由は、という名前が作成されたため、SimpleXMLが名前xmlns:mediaを指定するときにxmlns名前空間を使用したことが判明したためです。

1.コンストラクタ内の名前空間に指定します。

はここにあなたの問題の2つのソリューションです。

$rssXML = new SimpleXMLElement('<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" />'); 
$rssXML->addAttribute('version', '2.0'); 

2.あなたはそれを削除することを書いたpreg_replace

echo preg_replace('/xmlns:xmlns=""\s?/', '', $rssXML->asXML()); 
+0

は非常に明確に、非常に有用と右の説明。ありがとうございました。 :) – waxical

0

を使用してxmlns:xmlns=""を交換してください。最善の方法は、最初に置かないことです。

これはxmlns:(別の時間)を付けることによって動作します - それは何らかの形でのSimpleXMLで操作の特別なモードを有効にします - 空の名前空間URIを(そうでない場合、あなたが実際にそれを追加することを求める)を提供してない

$rssXML = new SimpleXMLElement('<rss/>'); 
$rssXML->addAttribute("version", '2.0'); 
$rssXML->addAttribute("xmlns:xmlns:media", "http://search.yahoo.com/mrss/"); 
$rssXML->addAttribute("xmlns:xmlns:dcterms", "http://purl.org/dc/terms/"); 
$rssXML->asXML('php://output'); 

<?xml version="1.0"?> 
<rss version="2.0" 
    xmlns:media="http://search.yahoo.com/mrss/" 
    xmlns:dcterms="http://purl.org/dc/terms/"/> 

はこの元々"Unable to add Attribute with Namespace Prefix using PHP Simplexml"で示唆された「カンニング」が、ミスした:

これは次の出力を作成します(あなたの読書の喜びのために美化)ここにいる。

+0

これは、追加されたノードが名前空間宣言ではなく属性であり、 "xmlns:"が名前空間接頭辞ではなく属性名のローカル部分の一部であるために機能します。無視されるので、 "xmlns"だけでなく、任意の接頭辞を使用できます。シリアライズするときは問題ありませんが、オブジェクトを操作するときに違いがあります(例:['SimpleXMLElement-> attributes()'](http://php.net/SimpleXMLElement.attributes)の引数と 'SimpleXMLElement- > children() '、または[' SimpleXMLElement-> addChild() '](http://php.net/SimpleXMLElement.addChild)の名前空間引数を参照してください)。 – outis

0

SimpleXMLElementは、間接的にのみ名前空間を追加できます。名前空間宣言、テキストノード、または他のノードタイプではなく、要素ノードと属性ノードだけを追加できるので、何とかSimpleXMLElement->addAttribute()またはSimpleXMLElement->addChild()を使用する必要があります。後者は新しい名前空間を子に追加するだけなので、ここでは使用しません。 addAttribute()は、属性とともに名前空間を指定された要素に追加するので、属性を削除すると、必要に応じて名前空間が残されます。

属性を明示的に削除する方法はありませんが、SimpleXMLElement->attributes()を使用して属性への参照を取得するために、「Remove a child with a specific attribute, in SimpleXML for PHP」に対するいくつかの回答としてunsetをタスクに適用できます。

<?php 
$rssXML = new SimpleXMLElement('<rss/>'); 
$rssXML->addAttribute("version", '2.0'); 
# add a dummy attribute to get the namespace 
$rssXML->addAttribute("media:_", '', "http://search.yahoo.com/mrss/"); 
unset($rssXML->attributes('media', TRUE)[0]); 
# and again 
$rssXML->addAttribute("dcterms:_", '', "http://purl.org/dc/terms/"); 
unset($rssXML->attributes('dcterms', TRUE)[0]); 

echo $rssXML->asXML(), "\n"; 

結果:

<?xml version="1.0"?> 
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" version="2.0"/> 

これはオーバー偽の名前空間の先頭に追加の属性として名前空間宣言を追加している利点は、それがむしろ何かを持っているために起こる属性よりも、名前空間として扱われますされていますその名前に名前空間接頭辞のように見えます。

var_export($rssXML->getDocNamespaces()); 

結果:

array (
    'media' => 'http://search.yahoo.com/mrss/', 
    'dcterms' => 'http://purl.org/dc/terms/', 
) 
関連する問題