XML parsen met extra entities gedefinieerd in DTD

Pagina: 1
Acties:

  • datadevil
  • Registratie: Maart 2001
  • Laatst online: 20:36
Hallo,

ik probeer een xml file te parsen die er zo uitziet:
XML:
1
2
3
4
5
<?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>

Omdat de entity Ø niet bestaat in XML is die in de DTD (of eigenljk in een .mod die de DTD inlaad) gedefinieerd.
PHP herkent dat ook, want voordat de DTD verwijzing goed stond kreeg ik een melding over een niet herkenbare entity, en die is nu weg, maar PHP laat het karakter niet zien.

Ik krijg dus bv. NIELS BIE ipv NIELS BIØIE

Dit is de php code:
PHP:
1
2
3
$options = LIBXML_DTDLOAD | LIBXML_NOENT | LIBXML_DTDVALID | LIBXML_NOCDATA;
$doc = simplexml_load_string ( $xml,null,$options );
echo $doc->document->header->namegroup->name->forenames."\n";


Iemand een idee wat ik verkeerd doe?

  • datadevil
  • Registratie: Maart 2001
  • Laatst online: 20:36
ok, ik ben een stap verder.
Als ik het zelfde element var_dump in plaats van echo krijg je dit
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
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)

Het karakter is er dus, maar hoe krijg ik die in de naam....

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Ik begrijp die entity definities in de DTD niet. Normaalgesproken doe je dat zoals in bijvoorbeeld http://www.w3.org/TR/xhtm...atin_1_Character_Entities. De entity wordt vervangen door hetgeen er achter staat. Bij jou wordt de entity dus door de letterlijke string
XML:
1
2
<symbol name='Oslash' unicode='00D8' type='html' glyph='@Oslash;' 
description='capital O, slash' ascii='O' > </symbol>

vervangen. Dat lijkt me niet de bedoeling.

Wie trösten wir uns, die Mörder aller Mörder?


  • datadevil
  • Registratie: Maart 2001
  • Laatst online: 20:36
Confusion schreef op woensdag 16 september 2009 @ 17:25:
Ik begrijp die entity definities in de DTD niet. Normaalgesproken doe je dat zoals in bijvoorbeeld http://www.w3.org/TR/xhtm...atin_1_Character_Entities. De entity wordt vervangen door hetgeen er achter staat. Bij jou wordt de entity dus door de letterlijke string
XML:
1
2
<symbol name='Oslash' unicode='00D8' type='html' glyph='@Oslash;' 
description='capital O, slash' ascii='O' > </symbol>

vervangen. Dat lijkt me niet de bedoeling.
In dit geval is het toch wel correct. Ik ben niet zo'n XML kenner, dus ik snapte uberhaupt eerst niet dat die DTD ingelezen werd om dan die string er in te plaatsen, maar dat snap ik nu wel.
Wat bij deze publisher (blijkbaar) het idee is is dat de XML naar heel veel output formaten kan, zowel naar print als naar web als naar pdf etc., en daarom stoppen ze meerdere alternatieve notaties in die symbol.

Ik heb het nu zo opgelost:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                $dom = new DOMDocument ( );
                $dom->resolveExternals = TRUE;
                $dom->substituteEntities = TRUE;
                $dom->loadXML ( $xml );
                
                $xpath = new DOMXpath ( $dom );
                
                $elements = $xpath->query ( "//symbol" );
                
                if (! is_null ( $elements )) {
                    foreach ( $elements as $element ) {
                        $fragment = $dom->createTextNode ( html_entity_decode ( '&#x' . $element->getAttribute ( 'unicode' ) . ';', ENT_QUOTES, 'UTF-8' ) );
                        $element->parentNode->replaceChild ( $fragment, $element );
                    }
                }