[PHP5] xml childs und attribute (xml2arr)

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [PHP5] xml childs und attribute (xml2arr)

    hm ... also irgendwie ist das alles recht umständlich oder ich bin zu doof dafür ;-)

    ich teste gerade etwas mit xml rum, das xml file sieht so aus:
    Code:
    <?xml version="1.1" encoding="UTF-8"?> 
     <comment>
      <author type="text" value="micha">
       <email type="text" value="user@host.com"/>
      </author>
      <heading type="text">
        überschrift
      </heading>
      <text type="text">
       comment-text
      </text>
     </comment>
    soll, wenns fertig ist, irgendwann mal eine klasse zum simplen zugriff auf xml daten werden, ala xml2arr oder so.
    das beispiel ist nicht übrezubewerten, es ist auch rein fiktiv um alle eventualitäten zu bedenken (manche packen die daten lieber in attribute, manche in den inhalt, ebenso childelemente usw)

    PHP-Code:
    class xmlfile implements IntXMLclass {

        protected 
    $filename '';
        protected 
    $domObj '';

        public function 
    __construct$filename=null ) {
            if (
    $filename != '') {
                
    $this->filename $filename;
                
    $domObj = new domDocument("1.0""UTF-8");
                
    $domObj->preserveWhiteSpace false;
                if (
    file_exists$filename )) {
                    
    $domObj->load("$filename");
                }
                
    $this->domObj $domObj;
            }
        }
    /* [REMOVE] jetzt nur zum testen drin */
    /* erstellt ein bunt gemischtes xml dokument, mit allem was so anfallen kann */
        
    function addcomment$author$heading$text$author_email='user@host.com' ) {
            
    $element $this->domObj->createElement("comment");
            
            
    $authorElement $this->domObj->createElement("author");
            
    $authorElement->setAttribute("type""text");
            
    $authorElement->setAttribute("value"$author);
            
    $element->appendChild($authorElement);

            
    $author_emailElement $this->domObj->createElement("email");
            
    $author_emailElement->setAttribute("type""text");
            
    $author_emailElement->setAttribute("value"$author_email);
            
    $authorElement->appendChild($author_emailElement);        
                    
            
    $headingElement $this->domObj->createElement"heading"$heading );
            
    $headingElement->setAttribute"type""text" );
            
    $element->appendChild($headingElement);
            
            
    $textElement $this->domObj->createElement("text"$text);
            
    $textElement->setAttribute("type""text");
            
    $element->appendChild($textElement);
            
    $this->domObj->appendChild($element);
        }

    /* holt alle attribute und gibt ein assz. array zurück */
        
    protected function getAttributes$element ) {
            if (
    $element->hasAttributes()) {
                
    $attrArr = array();
                
    $list $element->attributes;
                for (
    $i=0$i $list->length$i++) {
                    
    $attr $list->item($i);
                    
    $attrArr[$attr->nodeName] = $attr->nodeValue;
                }
                return 
    $attrArr;
            }
        }

    /* und abtauchen in die tiefen des xml dokuments ... */
    /* holt alle child und dazugehörigen attribute */
        
    protected function getChilds$element ) {
            if ( isset(
    $element) && $element->hasChildNodes()) {
                
    $childs = array();
                for( 
    $i=0$i $element->childNodes->length$i++) {
                    
    $domChild $element->childNodes->item($i);
                    
    $childs[$domChild->nodeName] = array();
                    if (!empty( 
    $domChild->nodeValue )) 
                        
    $childs[$domChild->nodeName]['content'] = $domChild->nodeValue;
                    if (
    $domChild->hasAttributes()) 
                        
    $childs[$domChild->nodeName]['attributes'] = $this->getAttributes$domChild );
                    if (
    $domChild->hasChildNodes())
                    
    $childs[$domChild->nodeName]['childs'] = $this->getChilds$domChild );
                                                
                }
                return 
    $childs;
            }
        }


    /* wieso kann ich nicht die nodelist behandeln wie eine element ?
    ** dann könnte ich mir eine methode + schleife sparen, aber so
    ** erstmal die nodelist durchlaufen und dann die childs davon */    
        
    protected function getFromNodeList($list) {
            
    $all = array();
            foreach (
    $list as $item) {
                
    $onetag = array( "tag" => $item->nodeName );
                
    $onetag['content'] = $item->nodeValue;
                if (
    $item->hasAttributes()) {
                    
    $onetag['attributes'] = $this->getAttributes($item);
                }
                 if (
    $item->hasChildNodes()) {
                      
    $onetag['childs'] = $this->getChilds$item );
                 }
                
    $all[] = $onetag;
            }
            return 
    $all;
        }
        
        
    /* in germany they say "von hinten durch..., bis hoch zur nase" :-) */
        
    public function getTagsArr($tagname) {
            
    $list $this->domObj->getElementsByTagName($tagname);
            return 
    $this->GetFromNodeList($list);
        }

            
    }

    $comms = new xmlfile('comments.xml');
    $comms->addcomment("micha""überschrift""comment-text");
    $comments $comms->GetTagsArr('comment'); 
    das ganze spuckt auch so ziemlich das aus was ich will, ein großes assz. array mit allem was an comments da is:
    Code:
    array(1) {
      [0]=>
      array(3) {
        ["tag"]=>
        string(7) "comment"
        ["content"]=>
        string(23) "überschriftcomment-text"
        ["childs"]=>
        array(3) {
          ["author"]=>
          array(2) {
            ["attributes"]=>
            array(2) {
              ["type"]=>
              string(4) "text"
              ["value"]=>
              string(5) "micha"
            }
            ["childs"]=>
            array(1) {
              ["email"]=>
              array(1) {
                ["attributes"]=>
                array(2) {
                  ["type"]=>
                  string(4) "text"
                  ["value"]=>
                  string(13) "user@host.com"
                }
              }
            }
          }
          ["heading"]=>
          array(2) {
            ["attributes"]=>
            array(1) {
              ["type"]=>
              string(4) "text"
            }
            ["childs"]=>
            array(1) {
              ["#text"]=>
              array(0) {
              }
            }
          }
          ["text"]=>
          array(2) {
            ["attributes"]=>
            array(1) {
              ["type"]=>
              string(4) "text"
            }
            ["childs"]=>
            array(1) {
              ["#text"]=>
              array(0) {
              }
            }
          }
        }
      }
    }

    die frage die sich mir bei dem ganzen stellt ist, wenn ich nicht in jeder klasse die die möglichkeit haben soll ihre daten in form von xml zu speichern mit DOMdocuments rumhandeln will, bleibt mir da nur eine solch "aufwendige" lösung um eben alle eventualitäten (verschachtelte tags usw) abzuhandeln, oder geht das auch "einfacher" ?

    sorry für die masse an code

    edit: ein paar kleinigkeiten ausgebessert
    Zuletzt geändert von psykadelik; 25.10.2004, 00:35.
    lg psykadeliK

    ---- schnapp ----

  • #2
    wenn du schon php5 verwendest, warum dann nicht auch gleich simplexml ?
    mfg,
    [color=#0080c0]Coragon[/color]

    Kommentar


    • #3
      wegen der verschachtelungsmöglichkeiten

      zitat:
      Edge Conditions

      While SimpleXML is a great tool for processing XML, its simplicity does come with a few drawbacks. Most notable among these is that processing mixed XML and text content with SimpleXML is very hard. For example, consider the following XML


      <?xml version="1.0"?>
      <flaw>
      <blurb>
      This <italic>is</italic> some sample <bold>text</bold> where
      SimpleXML <underline>will</underline> not behave well.
      </blurb>
      </flaw>


      Accessing $document->blurb with print_r() or var_dump() would return an element iterator that contained the contents of italic, bold, and underline. It would not, however, return the text surrounding those elements. This is because when given the choice between mixed elements and contents, SimpleXML will always choose to return the elements, and ignore the contents, of a particular tag.
      http://www.zend.com/php5/articles/php5-simplexml.php

      die frage ist halt eigentlich, ob man nicht nodeLists als elemente betrachten kann oder umgedreht.
      was da für grundlegende unterschiede sind ist schon klar, aber könnte ja noch einige "tricks" geben, daß der code nicht so aufgebläht ist...
      lg psykadeliK

      ---- schnapp ----

      Kommentar


      • #4
        ein typecast auf string hatte bei mir bisher immer funktioniert ..
        also ein simples echo oä.
        mfg,
        [color=#0080c0]Coragon[/color]

        Kommentar


        • #5
          Original geschrieben von Coragon Rivito
          ein typecast auf string hatte bei mir bisher immer funktioniert ..
          also ein simples echo oä.
          bei domlisten?
          lg psykadeliK

          ---- schnapp ----

          Kommentar


          • #6
            nein, ich rede immer noch von simplexml ..
            mit dom hab ich mich nie wirklich befasst
            mfg,
            [color=#0080c0]Coragon[/color]

            Kommentar


            • #7
              aber was bringt nen type cast bei xml objekten?
              also auch bei elementen usw, was bekommt man bei simplexml zurück, node oder value?
              lg psykadeliK

              ---- schnapp ----

              Kommentar

              Lädt...
              X