2009-08-13 10 views
11

Wyszukuję i przetwarzam pliki XML z innych źródeł, i trzeba je przetworzyć za pomocą niektórych XSLT-ów. Nie ma problemu. Korzystając z biblioteki PHP5 i DOM , wszystko jest proste. Dobrze się układało, do tej pory. Dzisiaj, funky znaków były w pliku XML - "inteligentne" cytaty z Worda, wygląda na jak. W każdym razie, DOMDocument-> load narzekał na nich, mówiąc, że nie były to UTF-8 i żeby określić kodowanie.Jak powiedzieć DOMDocument-> load() jakiego kodowania chcę użyć?

Lo i oto kodowanie nie jest określone w tych plikach XML. Jeśli I doda do nagłówka 'encoding = "iso-8859-1"', działa dobrze. Tarcie to Nie mam kontroli nad tymi plikami XML.

Odczytywanie pliku na ciąg znaków, modyfikowanie jego nagłówka i zapisywanie go na nowo do innej lokalizacji wydaje się być moją jedyną opcją, ale wolę zrobić to bez potrzeby używania tymczasowych kopii plików XML pod adresem wszystko. Czy jest jakiś sposób, aby po prostu powiedzieć analizatorowi, aby przeanalizował je tak, jakby były one iso-8859-1?

Odpowiedz

9

Czy to działa dla Ciebie?

$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->load($xmlPath); 

Edit: Ponieważ wydaje się, że to nie działa, co można zrobić, a nie jest podobna do istniejącej metody, ale bez pliku tymczasowego. Odczytu pliku XML z wykorzystaniem źródła tylko standardowe operacje IO (file_get_contents() czy coś), a następnie wykonać wszelkie zmiany w kodowaniu trzeba (iconv() lub utf8_decode()), a następnie użyć loadXML()

$myXMLString = file_get_contents($xmlPath); 
$myXMLString = utf8_decode($myXMLString); 
$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->loadXML($myXMLString); 
+1

próbował tego - to nie wydaje się wpływać na załadowanego dokumentu - od mojego czytania, I "Jestem całkiem pewien, że kodowanie zostanie zresetowane przez wywołanie load() – Loki

5

Nie znaleźli sposób aby ustawić domyślne kodowanie (jeszcze), ale tryb odzyskiwania jest w tym przypadku możliwy.
Kiedy libxml napotyka błąd kodowania i nie zostało jawnie ustawione kodowanie, przełącza się z unicode/utf8 na latin1 i kontynuuje parsowanie dokumentu. Ale w kontekście parsera właściwość wellFormed jest ustawiona na 0/fałsz. Rozszerzenie DOM DOM uważa dokument za ważny, jeśli jest on prawdziwy, jeśli atrybut obiektu DOMDocument to.

<?php 
// german Umlaut ä in latin1 = 0xE4 
$xml = '<foo>'.chr(0xE4).'</foo>'; 

$doc = new DOMDocument; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=false(default) : ', ($b) ? 'success':'failed', "\n"; 

$doc = new DOMDocument; 
$doc->recover = true; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=true : ', ($b) ? 'success':'failed', "\n"; 

drukuje

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 6 
with doc->recover=false(default) : failed 

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 11 
with doc->recover=true : success 

nadal pojawia się komunikat ostrzegawczy (które mogą być stłumione przez @ $ doc-> load()) i będzie to również widoczne w internal libxml errors (tylko raz, kiedy parser przełącza się z utf8 na latin1). Kod błędu dla tego konkretnego błędu będzie wynosił 9 (XML_ERR_INVALID_CHAR).

<?php 
$xml = sprintf('<foo> 
    <ae>%s</ae> 
    <oe>%s</oe> 
    & 
</foo>', chr(0xE4),chr(0xF6)); 

libxml_use_internal_errors(true); 
$doc = new DOMDocument; 
$doc->recover = true; 
libxml_clear_errors(); 
$b = $doc->loadxml($xml); 
$invalidCharFound = false; 
foreach(libxml_get_errors() as $error) { 
    if (9==$error->code && !$invalidCharFound) { 
     $invalidCharFound = true; 
     echo "found invalid char, possibly harmless\n"; 
    } 
    else { 
     echo "hm, that's probably more severe: ", $error->message, "\n"; 
    } 
} 
2

ony sposób aby określić kodowanie jest w deklaracji XML na początku pliku:

<?xml version="1.0" encoding="ISO-8859-1"?> 
+0

Jest to jedyna prawidłowa odpowiedź - patrz również http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8- prawidłowo – iquito

Powiązane problemy