PHP nie ma funkcji dekodowania encji bezpiecznego dla XML? Nie masz jakiegoś kodu xml_entity_decode?

PROBLEM: Potrzebuję pliku XML „zakodowanego w całości” przez UTF8; to znaczy, bez żadnej jednostki reprezentującej symbole, wszystkie symbole otoczone przez UTF8, z wyjątkiem tylko trzech, które są zarezerwowane dla XML, „&” (amp), „<” (lt) i „>” (gt). I,Potrzebujęwbudowany funkcja, która robi to szybko: przekształcić jednostki w prawdziwe znaki UTF8 (bez uszkodzenia mojego XML).
PS: to „problem ze światem rzeczywistym” (!); wPMC / czasopismana przykład zawiera 2,8 miliona artykułów naukowychspecjalny DTD XML (znany również jakoFormat JATS) ... Aby przetworzyć jako „zwykły tekst XML-UTF8”, musimy zmienić z encji numerycznej na znak UTF8.

PRÓBNE ROZWIĄZANIE: naturalną funkcją tego zadania jesthtml_entity_decode, ale niszczy kod XML (!), przekształcając zarezerwowane 3 symbole zarezerwowane dla XML.

Zilustrowanie problemu

Przypuszczać

  $xmlFrag ='<p>Hello world! &#160;&#160; Let A&lt;B and A=&#x222C;dxdy</p>';

Gdzie jednostki 160 (nbsp) i x222C (podwójna całka) muszą zostać przekształcone w UTF8, a zarezerwowane w XMLlt nie. Tekst XML będzie (po transformacji),

$ xmlFrag = '<p>Witaj świecie! Niech A&lt;B i A = ∬dxdy</p>';

Tekst „A <B” wymaga znaku zastrzeżonego w XML, więc MUSI zostać jakoA&lt;B.

Sfrustrowane rozwiązania

Próbuję użyćhtml_entity_decode do rozwiązania (bezpośrednio!) problemu ... Więc zaktualizowałem mój PHP do wersji 5.5, aby spróbować użyćENT_XML1 opcja,

  $s = html_entity_decode($xmlFrag, ENT_XML1, 'UTF-8'); // not working
                                                        // as I expected

Być może innym pytaniem jest„DLACZEGO nie ma innej możliwości zrobienia tego, czego oczekiwałem?” - jest ważny dla wielu innych aplikacji XML (!), nie tylko dla mnie.

Nie potrzebujęobejście jako odpowiedź ... Ok, pokazuję swoją brzydką funkcję, być może pomaga ci zrozumieć problem,

  function xml_entity_decode($s) {
    // here an illustration (by user-defined function) 
    // about how the hypothetical PHP-build-in-function MUST work
    static $XENTITIES = array('&amp;','&gt;','&lt;');
    static $XSAFENTITIES = array('#_x_amp#;','#_x_gt#;','#_x_lt#;');
    $s = str_replace($XENTITIES,$XSAFENTITIES,$s); 

    //$s = html_entity_decode($s, ENT_NOQUOTES, 'UTF-8'); // any php version
    $s = html_entity_decode($s, ENT_HTML5|ENT_NOQUOTES, 'UTF-8'); // PHP 5.3+

    $s = str_replace($XSAFENTITIES,$XENTITIES,$s);
    return $s;
  }  // you see? not need a benchmark: 
     //  it is not so fast as direct use of html_entity_decode; if there 
     //  was an XML-safe option was ideal.

PS: poprawione pota odpowiedź. Musi byćENT_HTML5 flaga, do konwersjinaprawdę wszystkie nazwane jednostki.

questionAnswers(5)

yourAnswerToTheQuestion