[PHP/XML] Uitlezen van children attr en subchildren elems

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Ypho
  • Registratie: April 2008
  • Laatst online: 16:02

Ypho

Allround Nerd

Topicstarter
Ik krijg om de zoveel tijd een XML bestand die ik wil uitlezen om in een MySQL database te plempen. Maar eerst is het nodig om de waarden uit te lezen uit de XML.

Zo ziet de XML er uit:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Show>
    <name>Naam van de show</name>
    <Episodelist>
        <Season no="1">
            <episode>
                <epnum>1</epnum>
                <seasonnum>01</seasonnum>
                <prodnum>1X001</prodnum>
                <airdate>[DATE]</airdate>
                <link>[LINK]</link>
                <title>[Episode title]</title>
            </episode>
        </Season>
        <Season no="2">
            <episode>
                ...
            ...
        ...
    ...
</Show>


De root node (Show) heeft een aantal elementen, titel, aantal seizoenen etc. Deze zijn niet heel belangrijk. Hetgeen dat ik eigenlijk wil is de waarde van alle seizoenen uitlezen, en daarbij de elementen van de children van die seizoenen, bijvoorbeeld:

- Season 1
-- Episode 1
-- Episode n
- Season 2
-- Episode 1
-- .....

Nu kan ik via DOMDocument alle episodes uitlezen, maar hierbij heb ik dus niet het seizoennummer. Let op: het element <seasonnum> heeft niet altijd de juiste waarde, vandaar dat ik de attribute-value van de parent wil hebben.

Kan iemand mij helpen met 贸f het verkrijgen van de parent attribute-value van een episode, 贸f het uitlezen van elk seizoen apart? Dit zal waarschijnlijk buiten het DOMDocument om moeten?

Ik heb DomElement->get_attribute_node gevonden, maar als ik met DOMDocument door de verschillende nodes heenloop, weet DomElement dan in welke node ik zit? Ik heb ook DomNode->parent_node gevonden om eventueel de parent uit te lezen, hiervoor eigenlijk dezelfde vraag.

馃儚 TCG Codex - Je volledige TCG verzameling in je broekzak ::: 馃崗 TCG Codex for iOS ::: 馃 TCG Codex for Android


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur庐

!litemod

Bij het resultaat van tvrage is het seasonnum niet het nummer van het seizoen, maar het episodenummer binnen dat seisoen.

Om je vragen te beantwoorden:
Kan iemand mij helpen met 贸f het verkrijgen van de parent attribute-value van een episode, 贸f het uitlezen van elk seizoen apart?
Helpen vast, maar vertel maar waar je vast zit.
Dit zal waarschijnlijk buiten het DOMDocument om moeten?
Nee, dat hoeft niet perse
weet DomElement dan in welke node ik zit?
Ja
Ik heb ook DomNode->parent_node gevonden om eventueel de parent uit te lezen, hiervoor eigenlijk dezelfde vraag.
Ja.

Ikzelf heb ook wat code geschreven om de xml van tvrage uit te kunnen lezen. Wat ik gedaan heb is om een methode te schrijven die een lijst episode nodes verwerkt. Deze geef ik naast die lijst ook het seizoen nummer mee.

Ik zoek dus de nodes met seizoen. Lees het attribuut uit en roep vervolgens de bovenstaande methode aan met de childnodes en het resultaat van het attribuut.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Kijk eens naar de functie simplexml_load_file of simplexml_load_string. Daarmee kun je makkelijk XML files/strings inlezen en makkelijk alle content (incl. attributes) bereiken die je wilt. De functie returned een object met daarin alle data, je kunt dus makkelijk var_dump(); gebruiken om te checken waar wat zit.

Acties:
  • 0 Henk 'm!

  • Ypho
  • Registratie: April 2008
  • Laatst online: 16:02

Ypho

Allround Nerd

Topicstarter
@Janoz
Ik wil dus ook tvrage uit kunnen lezen ;) Momenteel kom ik dus niet verder dan 贸f alle episodes uitlezen, 贸f alle seizoenen, het lukt nog niet om alle episodes binnen een seizoen uit te lezen.

Maar als ik dus bijvoorbeeld deze code heb...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$doc = new DOMDocument();
$doc->load("http://www.tvrage.com/feeds/episode_list.php?sid=3506");

$episodes = $doc->getElementsByTagName("episode");
foreach($episodes as $episode){     
    $titles = $episode->getElementsByTagName("title");
    
    echo $title = $titles->item(0)->nodeValue;
    echo "<br>";
    
}
?>

...leest en print hij alle afleveringen. Maar kan ik dan DomNode->parent_node gebruiken om de parent te pakken? Zo ja, is dit niet heel erg inefficient?

馃儚 TCG Codex - Je volledige TCG verzameling in je broekzak ::: 馃崗 TCG Codex for iOS ::: 馃 TCG Codex for Android


Acties:
  • 0 Henk 'm!

  • Noork
  • Registratie: Juni 2001
  • Niet online
Idd, ik vroeg me al af welke XML parser wordt gebruikt. SimpleXML is echt perfect om XML in te lezen met PHP.

Zie b.v. ook topics:
[PHP / SimpleXML] Nodes met '-' en '.' erin benaderen *
PHP en xml

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur庐

!litemod

Ypho schreef op maandag 27 april 2009 @ 10:31:
@Janoz
Ik wil dus ook tvrage uit kunnen lezen ;) Momenteel kom ik dus niet verder dan 贸f alle episodes uitlezen, 贸f alle seizoenen, het lukt nog niet om alle episodes binnen een seizoen uit te lezen.

Maar als ik dus bijvoorbeeld deze code heb...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$doc = new DOMDocument();
$doc->load("http://www.tvrage.com/feeds/episode_list.php?sid=3506");

$episodes = $doc->getElementsByTagName("episode");
foreach($episodes as $episode){     
    $titles = $episode->getElementsByTagName("title");
    
    echo $title = $titles->item(0)->nodeValue;
    echo "<br>";
    
}
?>

...leest en print hij alle afleveringen. Maar kan ik dan DomNode->parent_node gebruiken om de parent te pakken? Zo ja, is dit niet heel erg inefficient?
Probeer wat meer gebruik te maken van de voordelen van XML. Wanneer je je lus nu eens gebruikt voor het itereren over de seizoenen en dan voor elk seizoen de episodes opvraagt zoals je nu de title opvraagt. Je kunt gewoon een foreach binnen een foreach doen.


Trouwens. Bij TvRage hebben ze liever dat je services.tvrage.com gebruikt ipv www.tvrage.com

[ Voor 4% gewijzigd door Janoz op 27-04-2009 10:52 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Ypho
  • Registratie: April 2008
  • Laatst online: 16:02

Ypho

Allround Nerd

Topicstarter
Ik heb nu even een combi gemaakt tussen DomDocument en simple_xml met deze code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
error_reporting(E_ALL);

$doc = new DOMDocument();
$doc->load("http://services.tvrage.com/feeds/episode_list.php?sid=3506");

$seasons = $doc->getElementsByTagName("Season");
foreach($seasons as $season){       
    
    $episodes = $doc->getElementsByTagName("episode");
    /*foreach($episodes as $episode){
        $titles = $episode->getElementsByTagName("title");
        echo $title = $titles->item(0)->nodeValue;
        echo "<br>";
        // Loopt door alle episodes, elk seizoen weer
    }*/
    echo "<br>";
    echo "<br>";
    $s = simplexml_import_dom($season);
    print_r($s); // Print array voor ieder seizoen
    //echo $s['no']; // Print season number
    
}

Nu itereert DomDocument over de seizoenen heen, en per seizoen wordt er met simplexml een array gemaakt waar alles in staat voor dat seizoen. Ik heb het even zo gedaan omdat foreach over foreach (zie code) alle afleveringen pakt, ieder seizoen weer, en niet alleen afleveringen voor dat seizoen.

Een array per seizoen kan ook wel, die kan vast wel worden uitgelezen...al maak ik daar nooit echt gebruik van ;-)

Of hebben jullie betere suggesties?

馃儚 TCG Codex - Je volledige TCG verzameling in je broekzak ::: 馃崗 TCG Codex for iOS ::: 馃 TCG Codex for Android


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur庐
Het lijkt me dat je op regel 9 van je voorbeeld niet alle episodes van je document op moet halen maar alleen de episodes van dat season. Waarschijnlijk dus op deze manier
PHP:
1
$season->getElementByTagName( "episode" );

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Ypho
  • Registratie: April 2008
  • Laatst online: 16:02

Ypho

Allround Nerd

Topicstarter
Woy schreef op maandag 27 april 2009 @ 11:23:
Het lijkt me dat je op regel 9 van je voorbeeld niet alle episodes van je document op moet halen maar alleen de episodes van dat season. Waarschijnlijk dus op deze manier
PHP:
1
$season->getElementByTagName( "episode" );
God, je hebt gelijk, en ik maar denken "Waarom werkt het niet"....logisch. Ik kan deze DOM objecten niet gebruiken als array (om zo $season['no'] te printen). Hiervoor gebruik ik vooralsnog dus simplexml. Is hier iets makkelijkers voor, want het is eigenlijk zonde om elk DOM object via simplexml om te zetten naar een array om alleen maar een nummer te vinden.

馃儚 TCG Codex - Je volledige TCG verzameling in je broekzak ::: 馃崗 TCG Codex for iOS ::: 馃 TCG Codex for Android


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 21-09 10:43

Matis

Rubber Rocket

Ik weet niet of dit schieten met een bazooka op en mug wordt, maar kun je niet eenvoudig gebruik maken van het ZendFramework?

DOM zit er ook in http://framework.zend.com/manual/en/zend.dom.html

en een xmlrcp ook http://framework.zend.com/manual/en/zend.xmlrpc.html

Wat jij doet kan ook, maar het wiel opnieuw uitvinden hoeft niet altijd ;)

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • Ypho
  • Registratie: April 2008
  • Laatst online: 16:02

Ypho

Allround Nerd

Topicstarter
Oplossing gevonden voor het seasonnummer:
PHP:
1
$season->getAttribute("no");


Doet nu precies wat ik wil, thanks allen.

[ Voor 19% gewijzigd door Ypho op 27-04-2009 11:57 ]

馃儚 TCG Codex - Je volledige TCG verzameling in je broekzak ::: 馃崗 TCG Codex for iOS ::: 馃 TCG Codex for Android


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur庐
Ypho schreef op maandag 27 april 2009 @ 11:44:
[...]

God, je hebt gelijk, en ik maar denken "Waarom werkt het niet"....logisch. Ik kan deze DOM objecten niet gebruiken als array (om zo $season['no'] te printen). Hiervoor gebruik ik vooralsnog dus simplexml. Is hier iets makkelijkers voor, want het is eigenlijk zonde om elk DOM object via simplexml om te zetten naar een array om alleen maar een nummer te vinden.
zoveel verschil zit er toch niet tussen
PHP:
1
$season['no'];

of ( http://nl.php.net/manual/en/domelement.getattribute.php )
PHP:
1
$season->getAttribute( 'no' );

Dus waarom je het dan met simplexml wilt doen snap ik niet. Je kunt beter of helemaal overstappen op SimpleXML of het helemaal niet gebruiken IMHO.

offtopic:
Iets sneller reageren voortaan ;) Dit had je dus al gevonden.

[ Voor 4% gewijzigd door Woy op 27-04-2009 12:01 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1