Отсутствующие символы в разобранном XML-выводе с PHP5 - PullRequest
0 голосов
/ 16 сентября 2009

Я пытаюсь проанализировать следующий XML-файл:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE content PUBLIC "-//BLACKWELL PUBLISHING GROUP//DTD 4.0//EN" "http://www.blackwellpublishing.com/xml/dtds/4-0/bpg4-0.dtd">
<content dtdver="4.0" docfmt="xml">
....
<forenames>NIELS B&Oslash;IE</forenames><x> </x>

Сначала он не загружался, но теперь у меня есть код, который, по крайней мере, использует DTD для определения сущности типа &Oslash; (& Oslash;), но следующая проблема заключается в том, что он не показывает символ на выходе.

Это мой код анализа:

$options = LIBXML_DTDLOAD | LIBXML_NOENT | LIBXML_DTDVALID | LIBXML_NOCDATA;
$doc = simplexml_load_string ( $xml,null,$options );
echo $doc->document->header->namegroup->name->forenames."\n";

Это вывод:

NIELS BIE

Я тоже попробовал это с синтаксическим анализом DOM XML, а затем получился NIELS B IE (то есть с пробелом ..)

есть идеи?

Ответы [ 4 ]

2 голосов
/ 16 сентября 2009

Глядя на DTD, он говорит следующее (но без разрывов строки):

<!ENTITY Oslash 
    "<symbol name='Oslash' unicode='00D8'
     type='html' glyph='@Oslash;' description='capital O, slash' 
     ascii='O' > </symbol>"
>

Для любого читателя XML, использующего это DTD, это означает, что «Когда вы видите точное сочетание букв в источнике: &Oslash;, замените его следующим текстом: <symbol name='Oslash' unicode... > </symbol>

Это означает, что данные XML на самом деле выглядят так:

<forenames>NIELS B<symbol name='Oslash' unicode='00D8'
     type='html' glyph='@Oslash;' description='capital O, slash' 
     ascii='O' > </symbol>IE</forenames>

... что объясняет, почему он не отображается в вашем браузере. Обходным путем будет поиск в вашем XML-документе всех элементов <symbol>, чтение параметра unicode и замена их на него.


Если посмотреть дальше, то комментарии в верхней части DTD показывают, что они считали людей в вашей ситуации! Атрибут glyph в теге <symbol> - это стандартная HTML-сущность, используемая для этого символа, но с амперсандом, замененным на @.

10 read xml document
20 search for any <symbol> element
30 read the "glyph" attribute
40 remove the <symbol> element
50 replace the @ with an & in glyph
60 write that in the place of <symbol>
70 goto 20
2 голосов
/ 16 сентября 2009

DTD, который вы используете со своим XML-файлом, не содержит сущности Oslash. Таким образом, анализатор XML просто не знает, что делать с & Oslash; и возникает путаница и / или веселье.

Важно отделить понятие именованных сущностей в HTML (частью которого является Oslash) от понятия именованных сущностей в XML (apos, lt, gt, quot, amp). По сути, если это не HTML, там нет Oslash (по крайней мере, в общем случае, некоторые DTD могут иметь его, но это может быть совсем не тот символ, который вам нужен.

Другими словами; всегда используйте UTF-8. Всегда.

РЕДАКТИРОВАТЬ: Ø тоже в латинице-1.

1 голос
/ 16 сентября 2009

Если у вас правильная кодировка, вам не нужно экранировать &Oslash; (Ø). Попробуйте использовать Unicode, чтобы быть уверенным.

Если нет способа изменить поведение, попробуйте удалить экранирование HTML-сущностей, обратитесь к руководству по PHP.

0 голосов
/ 16 сентября 2009

хорошо, немного дальше, если я использую var_dump вместо echo, я получу это:

object(SimpleXMLElement)[22]
  public 'symbol' => 
  object(SimpleXMLElement)[21]
  public '@attributes' => 
    array
      'name' => string 'Oslash' (length=6)
      'unicode' => string '00D8' (length=4)
      'type' => string 'html' (length=4)
      'glyph' => string '@Oslash;' (length=8)
      'description' => string 'capital O, slash' (length=16)
      'ascii' => string 'O' (length=1)
  string ' ' (length=1)

Интересно, как я могу использовать это для создания полной строки вместе с содержимым имен

...