Knoten aus XML rauslösen und mit XSLT parsen

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

  • Knoten aus XML rauslösen und mit XSLT parsen

    Hallo,

    obwohl ich mich mit der DOM Problematik unter Javascript ganz gut auskenne, steige ich bei folgendem Problem einfach nicht durch:

    Als ersten den Code:
    PHP-Code:
    // Das Stylesheet in ein Objekt laden
    $xslDoc = new DOMDocument();
    $xslDoc->load('AttributesXSL-19.xsl');
    // Das Original XML in ein Objekt laden
    $xmlDoc = new DOMDocument();
    $xmlDoc->load('attributes.xml');
    // Den entsprechenden Knoten suchen
    $node $xmlDoc->getElementById('3072');
    // Ein neues (leeres) XML Objekt schaffen
    $newXML = new DOMDocument();
    $newXML->formatOutput true;
    $newXML->loadXML('<ebay></ebay>');
    // Denn Knoten in das neue XML Objekt importieren
    $node $newXML->importNode($node);
    // Den importierten Knoten als Kind einbinden
    $newXML->documentElement->appendChild($node);
    // Jetzt das ganze mit dem XSLT Processor verarbeiten
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xslDoc);
    echo 
    $proc->transformToXML($newXML); 
    Das ganze wird leider mit folgendem Fehler belohnt:
    Catchable fatal error: Argument 1 passed to DOMDocument::importNode() must be an instance of DOMNode, null given in ...

    Vielen Dank für eure Hinweise.
    Grüße Michael

  • #2
    Hallo,

    offenbar gibt es in attributes.xml kein Element mit der xml:id 3072. Wenn das Attribut nur id heißt, bedeutet das noch gar nichts. Besser du suchst das Element mit XPath raus.

    Gruß,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Ich habe mal das Stück aus der XML Datei herauskopiert (die Datei ist über 8MB groß):

      HTML-Code:
      <Characteristics>
      <CharacteristicsSet id='3072'  order='1' >
      <DomainName><![CDATA[Fitnessernährung]]></DomainName>
      <PresentationInstruction>
          <DomainName>Fitness Nutrition</DomainName>
          <Initial>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" id="47648" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input type="dropdown"/>
                      </Attribute>
                  </Widget>
              </Row>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" id="23718" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input type="dropdown"/>
                      </Attribute>
                  </Widget>
              </Row>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" id="47649" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input type="dropdown"/>
                      </Attribute>
                  </Widget>
              </Row>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" id="47650" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input type="dropdown"/>
                      </Attribute>
                  </Widget>
              </Row>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" helpId="1" id="10244" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input type="dropdown"/>
                      </Attribute>
                  </Widget>
              </Row>
              <Row>
                  <Widget type="normal">
                      <Attribute align="left" id="47651" quadrant="top">
                          <Label align="left" color="#000000" face="Arial, Helvetica, Sans-Serif" size="2"/>
                          <Input columns="2" type="checkbox"/>
                      </Attribute>
                  </Widget>
              </Row>
          </Initial>
      </PresentationInstruction>
      <CharacteristicsList>
      <Initial>
      <Attribute labelVisible='true'  id='3801' >
      <Label><![CDATA[SIFFTAS Group Pseudo Attribute]]></Label>
      <Type><![CDATA[2]]></Type>
      <EditType>0</EditType><ValueList count='2' >
      <Value id='-10' >
      <Name><![CDATA[-]]></Name>
      </Value>
      Ich dachte, das wenn "id" definiert ist ich diese auch ansprechen kann:
      HTML-Code:
      >CharacteristicsSet id='3072'>
      Die Variante mit Xpath habe ich auch schon probiert und das funktioniert auch, aber ich habe es nicht hinbekommen das Xpath Ergebnis wieder in ein neues XML Document einzubinden und mit XSLT zu parsen.

      Grüße
      Michael

      Kommentar


      • #4
        Zitat von francosdad Beitrag anzeigen
        Ich dachte, das wenn "id" definiert ist ich diese auch ansprechen kann
        Nein, bei HTML geht das, weil das id-Attribut in der DTD als vom Typ ID definiert ist. Ohne DTD weiß ein XML-verarbeitendes Programm nicht, dass es tatsächlich ein dokumentweit eindeutiger Schlüssel sein soll. Es kann ja auch zufällig id heißen oder z. B. nur unter gleichnamigen Elementen eindeutig sein, aber nicht dokumentweit.

        Zitat von francosdad Beitrag anzeigen
        Die Variante mit Xpath habe ich auch schon probiert und das funktioniert auch, aber ich habe es nicht hinbekommen das Xpath Ergebnis wieder in ein neues XML Document einzubinden und mit XSLT zu parsen.
        Bitte konkretisieren. XSLT parst nicht, es transformiert nur.

        Gruß,

        Amica
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          Wie Amica schon sagte - willst du mit PHP: DOMDocument::getElementById - Manual arbeiten geht es eben nur, wenn du eine DTD benutzt und du davor auch erfolgreich gegen diese validiert hast (siehe Manual).

          Kannst du dein Problem mit XPath nochmal konkretisieren? "... funktioniert auch..." und "...aber ich habe es nicht hinbekommen..." im gleichen Satz - da werd ich nich schlau draus.

          EDIT:
          Um bei deiner ursprünglich angepeilten Variante zu bleiben - da könnt auch noch folgendes für die interessant sein: http://de.php.net/manual/en/domeleme...dattribute.php - hab das selbst noch nicht probiert, sieht aber für deine Zwecke gut aus.
          Zuletzt geändert von Quetschi; 02.03.2010, 10:16.
          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
          Schön - etwas Geschichte kann ja nicht schaden.
          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

          Kommentar


          • #6
            Mein schneller Versuch mit xPath sieht wie folgt aus:

            PHP-Code:
            // Attributes.xml in DOM Objekt laden
            $xmlDoc = new DOMDocument();
            $xmlDoc->load('attributes.xml');

            // neues xPath Object und suche nach ID in DOM Objekt
            $xpath = new DOMXPath($xmlDoc);
            $newNode $xpath->query('@id = 3072');

            // Neues DOM Object 
            $newXML = new DOMDocument();
            $newXML->formatOutput true;
            $newXML->loadXML('<ebay></ebay>');

            // Versuch des Importes des xPath Ergebnisses als Knoten einzufügen
            $node $newXML->importNode($newNode);
            $newXML->documentElement->appendChild($node);

            // Ausgabe des neuen XML
            echo $newXML->saveXML(); 
            Das ganze wird jedoch wie folgt bemängelt:
            Catchable fatal error: Argument 1 passed to DOMDocument::importNode() must be an instance of DOMNode, instance of DOMNodeList given in ...

            Ich versteh das einfach nicht ...

            Kommentar


            • #7
              Ich finde das sogar sehr gut verständlich. XPath gibt dir nicht nur ein Element zurück, sondern eine Collection aller gefundener Elemente*. So sagt es dir Fehlermeldung und auch jede Doku zu XPath.

              Wenn du weißt, dass sowieso nur eins zurückkommen darf, weißt du mehr als XPath wissen kann und musst nur noch das erste Element aus der Collection auswählen, sofern sie überhaupt eins enthält (diesen Fall musst du natürlich auch prüfen).

              ___
              * ... wenn du es richtig machst. Du fragst XPath aber nur nach Attributen. Versuch's mal mit
              PHP-Code:
              $xpath->query('*[@id = 3072]'); 
              Gruß,

              Amica
              Zuletzt geändert von AmicaNoctis; 02.03.2010, 10:24.
              [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
              Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
              Super, danke!
              [/COLOR]

              Kommentar


              • #8
                Sieh dir mal an, was deine $newNode ist, bzw. schau im Manual nach, was du von einer Xpath-query zurückbekommst ;-)

                Sieh dir aber auch evtl. mein Edit im Post zuvor an.

                EDIT:
                bzw. du siehst ja in der Fehlermeldung schon, was dir die Query zurückgeliefert hat.

                Amica is 2fast4me
                Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                Schön - etwas Geschichte kann ja nicht schaden.
                Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                Kommentar


                • #9
                  Naja, die Query hat mir NULL zurückgeliefert, was für mich heißt, dass nichts drin ist.

                  Ich habe das jetzt mal so probiert:

                  PHP-Code:
                  $xmlDoc = new DOMDocument();
                  $xmlDoc->load('attributes.xml');

                  $xpath = new DOMXPath($xmlDoc);
                  $newNode $xpath->query('//CharacteristicsSet[@id = 3072]');

                  echo (
                  $newNode->length); 
                  Das Echo gibt mir 1 zurück, d.h. er hat etwas gefunden.

                  Wen ich diesen Knoten dann wieder einbinden will:

                  PHP-Code:
                  $newXML = new DOMDocument();
                  $newXML->formatOutput true;
                  $newXML->loadXML('<ebay></ebay>');

                  $node $newXML->importNode($newNode);
                  $newXML->documentElement->appendChild($node);

                  echo 
                  $newXML->saveXML(); 
                  bekomme ich trotzdem den Fehler:

                  Catchable fatal error: Argument 1 passed to DOMDocument::importNode() must be an instance of DOMNode, instance of DOMNodeList given in ...

                  Hast Du denn einen Hinweis auf eine gut verständliche xPath Docu?

                  Ich versuche immer einen Zusammenhang zu Javascript herzustellen. Wenn ich dort auf eine ID Zugreife, habe ich auch den gesamten Inhalt des Knotens.

                  Um vielleicht mein Ziel nochmal zu Dazustellen:

                  Ich habe eine XML Datei mit abertausenden "CharacteristicsSet", welche alle eine individuelle ID haben. Den Knoten mit der entsprechenden ID möchte herauslösen und mit einem XLS Stylesheet rendern.

                  Kommentar


                  • #10
                    Zitat von francosdad Beitrag anzeigen
                    Catchable fatal error: Argument 1 passed to DOMDocument::importNode() must be an instance of DOMNode, instance of DOMNodeList given in ...
                    Wie greift man auf ein Element einer DOMNodeList zu? Deinem Code fehlt nur noch eine Kleinigkeit - aber sorry - wir lassen die Leute selbst suchen - da hast du mehr davon.

                    EDIT:
                    Du solltest dir auch angewöhnen, das Manual zu Hilfe zu nehmen -> http://de.php.net/manual/en/domnodelist.item.php - steht alles drin und wartet nur darauf gelesen zu werden.

                    Nochmal EDIT:
                    Ich versuche immer einen Zusammenhang zu Javascript herzustellen. Wenn ich dort auf eine ID Zugreife, habe ich auch den gesamten Inhalt des Knotens.
                    Ja, weil du dort getElementByID benutzt und das liefert dir direkt den Knoten, der den gesuchten, eindeutigen Bezeichner enthält. In PHP müsstest du wie gesagt zuerst gegen eine DTD validieren, damit du so vorgehen kannst (oder mal http://de.php.net/manual/en/domeleme...dattribute.php probieren wie ich ein paar Posts vorher schon schrieb). Bei einer XPath-Query erhältst du dagegen eine Liste, mittels derer du dann auf die gefundenen Knoten zugreifen kannst.
                    Zuletzt geändert von Quetschi; 02.03.2010, 11:14.
                    Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                    Schön - etwas Geschichte kann ja nicht schaden.
                    Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                    Kommentar


                    • #11
                      So, die Fehlermeldung ist weg!

                      Wenn ich die Werte des Knotens ausgeben lassen, dann werden diese korrekt aufgelistet:

                      PHP-Code:
                      echo ($newNode->item(0)->nodeValue); 
                      Binde ich aber den neuen Knoten ein:

                      PHP-Code:
                      $newXML = new DOMDocument();
                      $newXML->formatOutput true;
                      $newXML->loadXML('<ebay></ebay>');

                      $node $newXML->importNode($newNode->item(0));
                      $newXML->documentElement->appendChild($node);

                      echo 
                      $newXML->saveXML(); 
                      Ist die Ausgabe leer!

                      Der Quelltext zeigt mir folgendes:
                      HTML-Code:
                      <?xml version="1.0"?>
                      <ebay>
                        <CharacteristicsSet id="3072" order="1"/>
                      </ebay>
                      Das heißt die Kindknoten werden nicht mit übergeben. Wie bekomme ich diese eben mit kopiert?

                      Kommentar


                      • #12
                        Zitat von francosdad Beitrag anzeigen
                        Das heißt die Kindknoten werden nicht mit übergeben. Wie bekomme ich diese eben mit kopiert?
                        Und wieder hilft ein Blick ins Manual: PHP: DOMDocument::importNode - Manual
                        Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                        Schön - etwas Geschichte kann ja nicht schaden.
                        Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                        Kommentar


                        • #13
                          Naja, wer lesen kann ist klar im Vorteil ...

                          Als erstes natürlich erstmal vielen Dank. Der Knoten wird kopiert und OHNE Fehlermeldung ausgegeben ;-)

                          Hast Du einen Hinweis auf eine gute XSLT Doku bzw. Tutorial, denn das rendern steht jetzt auf der Agenda.

                          Grüße
                          Michael

                          Kommentar


                          • #14
                            Meine persönlichen Anlaufstellen zu dem Thema:

                            SELFHTML: XML / Darstellung von XML-Daten
                            PHP: XSL - Manual
                            Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                            Schön - etwas Geschichte kann ja nicht schaden.
                            Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                            Kommentar


                            • #15
                              @Michael
                              Mich würde Interresieren ob du weiter gekommen bist , mit den Rendern e.t.c
                              Ich hänge beim Rendern über PHP fest

                              Kriege Folgenende Meldung :
                              xmlXPathCompOpEval: function node-set not found in...
                              So wie es ausehen tut ist die xsl von Ebay nicht mit php xml Path kompatibel

                              Mfg
                              Martin

                              Kommentar

                              Lädt...
                              X