2009-10-20 8 views
7

tworzę kanał Atom, gdy próbowałem poniżej, aby dodać xmlns:i jako atrybut -Nie add namespace z phps SimpleXML

$node->addAttribute("xmlns:i","http://www.w3.org/2001/XMLSchema-instance"); 

mam to jako wyjście -

i="http://www.w3.org/2001/XMLSchema-instance" 

"xmlns:" części został odcięty. czy muszę uciec z : -znak? Czy jest to jakikolwiek inny sposób dodania tej przestrzeni nazw?

Odpowiedz

20

Jeśli chcesz dodać atrybut z obszaru nazw/prefiksu i do węzła $, nie przejmuj się wcześniej zadeklarowaniem przestrzeni nazw. Po prostu użyj trzeciego parametru funkcji addAttribute(), aby podać obszar nazw uri dla prefiksu, którego używasz w pierwszym parametrze.

$node = new SimpleXMLElement('<root></root>'); 
$node->addAttribute("i:somename", "somevalue", 'http://www.w3.org/2001/XMLSchema-instance'); 
echo $node->asXml(); 

drukuje

<?xml version="1.0"?> 
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:somename="somevalue"/> 

Jeśli sam atrybut nie jest potrzebna, można następnie zabrać je ze unset() pozostawiając deklarację przestrzeni nazw.

unset($node->attributes('i', TRUE)['somename']); 
+4

To wydaje się taki odpadów. To deklaruje przestrzeń nazw w każdym wierszu zamiast tylko na root. –

+1

Myślę, że dodaje do atrybutu "dummy", aby przekonać SimpleXMLElement do dodania deklaracji przestrzeni nazw. Brzydki (ale błąd PHP, nie VolkerK), ale działa, jeśli nie masz nic przeciwko dodatkowemu atrybutowi. –

+1

Najlepszym rozwiązaniem jest to, które oferuje Olivier 'Ölbaum' Scherler –

17

Jeśli nie chcesz mieć dodać atrybut atrapę do elementu głównego, można zadeklarować na niej nazw ręcznie dodając atrybut xmlns dla prefiksu i:

<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 

Aby to zrobić i jako podpowiedź w istniejącej odpowiedzi (Unable to add Attribute with Namespace Prefix using PHP Simplexml), musisz poprzedzić nowy atrybut wartością xmlns: (ponieważ prefiks przestrzeni nazw o nazwie xmlns: nie jest zadeklarowany w dokumencie). A ponieważ xmlns: jest częścią nazwy tego atrybutu, to therfore potrzebne są dwa wystąpienia xmlns:

$uri = 'http://www.w3.org/2001/XMLSchema-instance'; 

$root = new SimpleXMLElement('<root/>'); 
$root->addAttribute('xmlns:xmlns:i', $uri); 
         ###### 

$child = $root->addChild('foo'); 
$child->addAttribute('xmlns:i:bar', 'baz'); 
         ###### 

echo $root->asXml(); 

Daje (sformatowane ręcznie dla czytelności):

<?xml version="1.0"?> 
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <foo i:bar="baz"/> 
</root> 

Więc to xmlns: Prefiksacja wydaje się go oszukać. Zauważ, że jeśli przeładować element po ustawienie tego atrybutu, możliwe jest korzystanie z URI przestrzeni nazw, jak również podczas dodawania dzieci, i to bez podania prefiksu:

$root = new SimpleXMLElement($root->asXML()); 

$child = $root->addChild('foo'); 
$child->addAttribute('i:bar', 'bazy', $uri); 
             #### 

echo $root->asXml(); 

daje (ponownie, sformatowany ręcznie):

<?xml version="1.0"?> 
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <foo i:bar="baz"/> 
    <foo i:bar="bazy"/> 
</root> 

Ten drugi przykład wydaje się bliższy zamierzonemu (lub przynajmniej oczekiwanemu) użyciu.

Należy pamiętać, że jedynym sposobem, aby to zrobić poprawnie, byłoby użycie bardziej kompletnych (ale niestety również bardziej złożonych i bardziej szczegółowych) klas DOMDocument. Jest to opisane w How to declare an XML namespace prefix with DOM/PHP?.

+0

Dziękuję za edycję, hakre. –

+7

Nie trzeba poprzedzać przedrostkiem '' xmlns: "', można poprzedzać prefiksem dowolną starą śmieci (w tym białą spacją!) Pod warunkiem, że podasz _something_ przed pierwszym dwukropkiem ':', na przykład '$ child-> addAttribute ("HACK: i: bar", "baz"); '. Innymi słowy, nie jest to obsługiwany, ale niejasny sposób na uzyskanie prefiksu xmlns, po prostu "oszukujemy" podejrzanego parsera. Dlatego nie możemy polegać na tym, aby działać w przyszłości. Powinniśmy używać DOM do tego, dopóki _proper_ ns wsparcie prefiksu nie zostanie dodane do SimpleXMLElement. Ten sam hack PS działa również w celu prefiksowania nazw elementów. – Sepster

+1

Parser jest podejrzany? W PHP? Jestem zszokowany. Wstrząśnięty! –

3

Znalazłem to szukając tego samego, i żadna z odpowiedzi naprawdę nie zadziałała dla mnie. Próbowałem więc innej trasy. Jeśli SimpleXML nie zarządza poprawnie przestrzenią nazw, użyj zamiast niej DOM.

Tak, coś jak to powinno działać:

$s = new simplexmlelement('<root/>'); 
$d = dom_import_simplexml($s); 
$d->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:i", "http://www.w3.org/2001/XMLSchema-instance"); 
$s->addChild("bar", "bazy", "http://www.w3.org/2001/XMLSchema-instance"); 
$f = $s->addChild("foo", "quux"); 
$f->addAttribute("i:corge", "grault", "http://www.w3.org/2001/XMLSchema-instance"); 

To spowoduje to:

<?xml version="1.0"?> 
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <i:bar>bazy</i:bar> 
    <foo i:corge="grault">quux</foo> 
</root>