2012-02-29 9 views
7

mam ten kod:Get dzieci xml bez wymiany podmioty html w PHP

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
$strXml = ' 
<root> 
<kid><div>ABC&#8226;&#62;</div></kid> 
<kid2>DEF</kid2> 
</root>'; 

$objXml = new SimpleXMLElement($strXml); 
$arrNodes = $objXml->xpath('/root/*'); 
foreach($arrNodes as $objNode) { 
    /* @var $objNode SimpleXMLElement */ 
    echo $objNode->asXML(); 
} 

Kod pobiera pierwsze dzieci korzenia i wyświetla zawartość. Problem polega na tym, że jednostki html są konwertowane na znaki. Czy istnieje sposób, w jaki kod wyprowadza początkową zawartość XML bez jakiejkolwiek konwersji?

+0

Czy są naprawdę skonwertowane, czy przeglądasz dane wyjściowe w przeglądarce? Spójrz na źródło strony, jeśli ... –

+0

Są konwertowane. – danidacar

+0

Uruchamiając twój kod, widzę '# &62;' jest wyprowadzany jako '<'. –

Odpowiedz

1

Czy istnieje sposób, w jaki kod wyprowadza początkową zawartość XML bez konwersji?

nr

marginesie: Dlaczego cię to obchodzi? Są tą samą postacią.

+0

Dbasz o to, jeśli masz klienta, który w ostatecznym rozrachunku domaga się tego samego wyniku, nawet jeśli pod względem technicznym jest taki sam. – danidacar

+0

Naprawdę nie, ale to tylko ja. Tak czy inaczej, masz odpowiedź. :) – salathe

0

SimpleXML/DOMDocument/etc zawsze będzie konwertować te elementy, ponieważ ponumerowane encje nie są poprawne.

Więc albo:

  • Epic wyszukiwania i zamiany.
  • A może naprawić to, co generuje XML?
+0

Obiekty numeryczne są poprawne w XML. – danidacar

+0

Zgodnie z SimpleXML itp. To nie jest ... technicznie poprawne, ale ... http://www.w3.org/TR/REC-xml/#charsets – Ing

+0

@IngmarBoddington można znaleźć wszelkie raporty o błędach lub dyskusje na ten temat ? Wydaje mi się to dziwnym zachowaniem i nie mogę w tej sprawie nic znaleźć. Wygląda na to, że dotyczy * wszystkich * różnych plików XML PHP (o których mi wiadomo). –

0

To wydaje mi się bardzo dziwnym zachowaniem i nie mam szczęścia szukając informacji.

Wygląda na to, że dotyczy wszystkich odpowiednich XML stuff. Warto również zauważyć, że znaki są zapisywane jako zwykłe znaki, gdy XML jest analizowany:

php > print_r($objXml); 
SimpleXMLElement Object 
(
    [kid] => SimpleXMLElement Object 
     (
      [div] => ABC•> 
     ) 

    [kid2] => DEF 
) 

... one zapisane jako podmioty gdy XML jest konwertowana do tekstu. Zgaduję, że wszystko używa tej samej wewnętrznej procedury do konwersji na tekst.

Jeśli naprawdę potrzebujesz tej funkcji, można utworzyć własną funkcję do ucieczki znaki, coś takiego:

// function to escape some utf8 characters with xml character reference 
function xmlCharEncode($string) { 

    $out = ''; 

    $len = mb_strlen($string, 'UTF-8'); 

    for ($i = 0; $i < $len; $i++) { 

    $char = mb_substr($string, $i, 1, 'UTF-8'); 

    $convmap = array(
     60, 60, 0, 0xffff, // < 
     62, 62, 0, 0xffff, // > 
     38, 38, 0, 0xffff, // ampersand 
     // you may want to filter quotes or other characters here 
     127, 0xffff, 0, 0xffff, // everything after basic latin 
    ); 

    $enc = mb_encode_numericentity($char, $convmap, 'UTF-8'); 

    $out .= $enc; 

    } 

    return $out; 

} 

... a następnie użyć XMLReader i XmlWriter napisać XML przy użyciu niestandardowego charakteru ucieczki rutyna:

// read and write your xml string 

$r = new XMLReader(); 
$w = new XMLWriter(); 
$r->xml($strXml); 
$w->openMemory(); 

while($r->read()) { 

    switch ($r->nodeType) { 

    // write elements, attributes, and text nodes 

    case XMLReader::ELEMENT: 
     $w->startElement($r->name); 
     while ($r->moveToNextAttribute()) { 
     echo $w->outputMemory(true); 
     $w->writeAttribute($r->name, $r->value); 
     } 
     break; 

    case XMLReader::END_ELEMENT: 
     $w->endElement(); 
     break; 

    case XMLReader::TEXT: 
     $w->writeRaw(xmlCharEncode($r->value)); // the magic happens here 
     break; 

    } 

    echo $w->outputMemory(true); 

} 

nie jestem przekonany, to jest warta, ale przynajmniej masz pomysł jakie rzeczy można zrobić, aby dostać tę pracę.

To będzie działać z twoim oryginalnym przykładem, przy okazji.