phpbar.de logo

Mailinglisten-Archive

[php] 1/2 OT: xml-schema fuer Artikel

[php] 1/2 OT: xml-schema fuer Artikel

Enrico Weigelt weigelt at metux.de
Don Mai 6 21:32:10 CEST 2004


* Peter Bieling <network at media-palette.de> verrauschte die Liste mit folgendem:

Hi,

>  > ich habe mir grad einen xml-loader für Artikel gebaut und
> >wollte mal um Eure Meinung fragen, ob ihr das Schema für 
> >sinnvoll haltet ...
> 
> mich würde zuerst mal der Loader interessieren. Meinst Du einen XML-Parser?

Ja. Ich hab mal das File angehangen. 
Ist hoffentlich einigermaßen selbsterklärend ;-)

Der Loader selbst steckt in article_load_xml.inc, im File xml-escape.inc
steckt ein kleiner workaround für ein Problem das ich mit expat hab:
er meckert, daß bestimmte entities nicht definiert sind ... 

<snip>
> Ich fürchte da hat jeder seine eigenen Ansprüche. Sicherlich gibt es da 
> auch schon fertige Lösungen in XML für die verschiedensten Zwecke. Hast 
> Du mal recherchiert?
Nein, dazu bin ich noch nicht gekommen - das eigene Problem geht vor ;-)
Ich hatte ja erst gedacht, daß ich für verschiene Artikeltypen
untschiedliche Schemata bräuchte, aber (abgesehen von Bildern) ist es 
mir bis dato erstmal gelungen, alle meine Erfordernisse in einem einfachen
Schema unterzubringen. Beispiele siehe Attachement.

<snip>
> Ich hatte erst vermutet, Du wolltest mit Namespaces arbeiten. Spätestens 
> hier sieht das aber nicht mehr so aus. Was Du machst ist zwar nicht 
> verboten aber schlechter Stil:
*schnief*
Muß eingestehen, daß ich noch nicht wirklich weisß, wie die 
Namespaces richtig funktionieren. 

Ich hatte ja erst gedacht, ich könnte dem Expat einfach sagen, daß 
er nur alle Tags mit einem bestimmten Prefix ("ARTICLE:") auswerfen und
alles andere als CDATA behandeln soll. Leider hab ich dazu nix gefunden,
sodaß ich das dann selbst machen mußte.

<snip>
> Warum schachtelst Du nicht die Elemente? Ich finde die Hierarchie gehört 
>  in das XML-Dokument und nicht in die Namen der Elemente.
> <article>
>    <linklist>
>        <text>...</text>
>    </linklist>
> </article>
Damit ich keinen Konflikt mit den (X)HTML-Elementen bekomme.

<snip>
> >In den CDATA dürfen dann auch ander XML-Tags (auch XHTML) verwendet werden.
> 
> Logisch, muss man halt entsprechend deklarieren. Beispiel aus Selfhtml8:
> <![CDATA[<Element>dieses Element wird nur als Zeichenfolge 
> ausgegeben</Element>]]>
hmm, ich kenne mich mit XML noch nicht wirklich aus. Vielleicht kannst Du
das ja mal etwas konkretisieren :)

<snip>
> >Das Ganze wird von meinem Loader in eine einfache, verschachtelte 
> >Array-Struktur gelegt, mit der ich dann Templates fülle.
> 
> Man könnte dafür natürlich auch XSLT verwenden. Dann spart man sich den 
> Umweg über Deinen Loader. ;-)
Das braucht aber wieder eine entsprechende extension und frißt sicher
auch 'n bissl Zeit. Außerdem bau ich nunmal generell alles mit patTemplate,
und da möchte ich nicht noch XSLT dazwischenwerfen.


cu
-- 
---------------------------------------------------------------------
 Enrico Weigelt    ==   metux IT service

  phone:     +49 36207 519931         www:       http://www.metux.de/
  fax:       +49 36207 519932         email:     contact at metux.de
  cellphone: +49 174 7066481
---------------------------------------------------------------------
 -- DSL ab 0 Euro. -- statische IP -- UUCP -- Hosting -- Webshops --
---------------------------------------------------------------------
-------------- nächster Teil --------------
<?php

## FIXME: make this reentrant compatible!

require_once ( LIB_METUX.'ds/xml-escape.inc' );

function article_load_xml ( $config )
{
    global $__article_load_xml_stat;   

    $__article_load_xml_stat = array ( config => $config );
    $_st = & $__article_load_xml_stat;
    
    $xml_parser = xml_parser_create();
    xml_set_element_handler ( $xml_parser, '__article_load_xml_startElement', '__article_load_xml_endElement');
    xml_set_character_data_handler ( $xml_parser, '__article_load_xml_cdata' );

    if (!($xml_text = _xml_escape_encode(@implode('', at file($config{'data_source'})))))
	return;

    if (!xml_parse($xml_parser, $xml_text))
	die ( "XML error: ".
	    xml_error_string(xml_get_error_code($xml_parser)).
	    " at line ".
	    xml_get_current_line_number($xml_parser)
        );

    xml_parser_free ($xml_parser);

    return $_st{'data'};
}

function __article_load_xml_cdata ( $parser, $data )
{
    global $__article_load_xml_stat;    
    $_st = & $__article_load_xml_stat;
    $_st{'current-text'} .= _xml_escape_decode ( $data );
}

function __article_load_xml_startElement ( $parser, $name, $attrs_in )
{
    global $__article_load_xml_stat;    
    $_st = & $__article_load_xml_stat;
    
    foreach ( $attrs_in as $a_walk => $a_cur93 )
	$attrs{strtolower($a_walk)} = _xml_escape_decode ( $a_cur93 );

    $name = strtoupper($name);
    
    if (preg_match('~^ARTICLE:([A-Za-z0-9\-\:]+)~', $name, $_res))
    {
	switch ( $elem = $_res[1] )
	{
    	    case 'ARTICLE':
	    case 'TITLE':
	    case 'ABSTRACT':
	    case 'OUTLINE':
	    case 'EDITORIAL':
	    case 'CAPTION':
	    case 'TEXT':
	    case 'HISTORY':
	    case 'LINKLIST':
	    case 'LINKLIST:TEXT':
	    case 'LINKLIST:LINK':
		$_st{'current-elem'} = $elem;
		break;
		
	    default:
		print "STARTELEM: unknown elem: $name<br>\n";
	}
	$_st{'current-text'} = '';
	$_st{'current-attr'} = $attrs;
    }
    else
    {
	$addtext = '<'.$name;
	if (is_array($attrs))
	    foreach ( $attrs as $a_walk => $a_cur93 )
		$addtext .= ' '.$a_walk.'="'.str_replace ( '"', '&quot;', $a_cur93 ).'"';
	$addtext .= ">\n";

	$_st{'current-text'} .= $addtext;
    }
}

function __article_load_xml_endElement($parser, $name)
{
    global $__article_load_xml_stat;
    $_st = & $__article_load_xml_stat;

    $name = strtoupper ( $name );
    if (preg_match('~^ARTICLE:([A-Za-z0-9\-\:]+)~', $name, $_res))
    {
	switch ( $elem = $_res[1] )
	{
	    case 'ARTICLE':
		break;
	    
	    case 'TITLE':
		$_st{'data'}{'title'} .= $_st{'current-text'};
		break;

	    case 'ABSTRACT':
		$_st{'data'}{'abstract'} .= $_st{'current-text'};
		break;

	    case 'OUTLINE':
		$_st{'data'}{'outline'} .= $_st{'current-text'};
		break;

	    case 'EDITORIAL':
		$_st{'data'}{'editorial'} .= $_st{'current-text'};
		break;
			
	    case 'TEXT':
		$_st{'data'}{'par'}[] = array 
		(
		    type 	=> 'text',
		    content	=> $_st{'current-text'},
		    id		=> '',
		);
		break;
	    
	    case 'CAPTION':
		if ($id = $_st{'current-attr'}{'id'})
		{    
		    $_st{'data'}{'par'}[] = array 
		    (
			type 	=> 'caption-id',
			content	=> $_st{'current-text'},
			id	=> $id
	    	    );
		    $_st{'data'}{'index'}[] = array
		    (
			id	=> $id,
			text	=> $_st{'current-text'}
		    );
		}
		else
		{
	    	    $_st{'data'}{'par'}[] = array 
	    	    (
			type 	=> 'caption',
			content	=> $_st{'current-text'},
			id	=> ''
	    	    );
		}
		break;
	
	    case 'HISTORY':
		$_st{'data'}{'history'}[] = array
		(
		    content	=> $_st{'current-text'},
		    date	=> $_st{'current-attr'}{'date'},
		    email	=> $_st{'current-attr'}{'email'},
		    name	=> $_st{'current-attr'}{'name'}
		);
		break;
		
	    case 'LINKLIST':
		break;
	
	    case 'LINKLIST:TEXT':
		$_st{'data'}{'linklist-text'} = $_st{'current-text'};
		break;
		
	    case 'LINKLIST:LINK':
		$_st{'data'}{'linklist-data'}[] = array
		(
		    content	=> $_st{'current-text'},
		    type	=> $_st{'current-attr'}{'type'},
		    target	=> $_st{'current-attr'}{'target'}
		);
		break;
		
	    default:
		print "ENDELEM: unknown elem: $name<br>\n";
	}
	unset ( $_st{'current-elem'} );
	unset ( $_st{'current-text'} );
    }
    else
    {
	$addtext = '</'.$name;
	if (is_array($attrs))
	    foreach ( $attrs as $a_walk => $a_cur93 )
		$addtext .= ' '.$a_walk.'="'.str_replace ( '"', '&quot;', $a_cur93 ).'"';
	$addtext .= ">\n";
		
	__article_load_xml_cdata ( $parser, $addtext );
    }
}
-------------- nächster Teil --------------
<?php

function _xml_escape_encode ( $text )
{
    return
    str_replace ( '<BR>',       '<BR/>',
    str_replace ( '&eq',	'__==__eq__==__',
    str_replace ( '&lt;',	'__==__lt__==__',
    str_replace ( '&rt;',	'__==__rt__==__',
    str_replace ( '&auml;', '__==__auml__==__', 
    str_replace ( '&ouml;', '__==__ouml__==__',
    str_replace ( '&uuml;', '__==__uuml__==__',
    str_replace ( '&Auml;', '__==__Auml__==__',
    str_replace ( '&Ouml;', '__==__Ouml__==__',
    str_replace ( '&Uuml;', '__==__Uuml__==__',
    str_replace ( '&szlig;','__==__szlig__==__', $text )))))))))));
}

function _xml_escape_decode ( $text )
{
    return
    str_replace ( '__==__eq__==__',	'&eq;',
    str_replace ( '__==__lt__==__',	'&lt;',
    str_replace ( '__==__rt__==__',	'&rt;',
    str_replace ( '__==__auml__==__',  '&auml;',
    str_replace ( '__==__ouml__==__',  '&ouml;',
    str_replace ( '__==__uuml__==__',  '&uuml;',
    str_replace ( '__==__Auml__==__',  '&Auml;',
    str_replace ( '__==__Ouml__==__',  '&Ouml;',
    str_replace ( '__==__Uuml__==__',  '&Uuml;',
    str_replace ( '__==__szlig__==__', '&szlig;', $text ))))))))));
}

php::bar PHP Wiki   -   Listenarchive