0

I'm working on parsing some XML files using Xpath. I want to select one specific Category node and his parent node (Sport) with one expression?!

XML document: livescore_full.xml

<? xml version = "1.0" encoding = "UTF-8" ?>
<LivescoreData generatedAt="2013-08-18T09:41:19 CEST" type="full">
    <Sport SportId="1">
        <Name language="en">Soccer</Name>
        <Category CategoryId="48">
            <Name language="en">Argentina</Name>
            <Tournament TournamentId="68" UniqueTournamentId="155">
                <Name language="en">Primera Division, Torneo Inicial</Name>
            </Tournament>
        </Category>
        <Category CategoryId="49">
            <Name language="en">Brazil</Name>
            <Tournament TournamentId="69" UniqueTournamentId="156">
                <Name language="en">Brazil Primera Division</Name>
            </Tournament>
        </Category>
    </Sport>
    <Sport SportId="2">
        <Name language="en">Basketball</Name>
        <Category CategoryId="55">
            <Name language="en">Spain</Name>
            <Tournament TournamentId="545" UniqueTournamentId="453">
                <Name language="en">Primera Division, Torneo Inicial</Name>
            </Tournament>
        </Category>
        <Category CategoryId="56">
            <Name language="en">England</Name>
            <Tournament TournamentId="654" UniqueTournamentId="5656">
                <Name language="en">England</Name>
            </Tournament>
        </Category>
    </Sport>
</LivescoreData>


 $xml = simplexml_load_file("livescore_full.xml");
 $data = $xml->xpath('//Category[@CategoryId="48"]'); 
 print_r($data); // only return data for specific Category node

$data contains data about Category node id=48, but there is no information about the sport id and sport name.

How to write Xpath rule to select Sport and Category data using CategoryId attribute? I tried some variations with the ancestor-or-self, but without success.

HeyHo
  • 1
  • 1
  • 3

2 Answers2

0
"/LiveScoreData/Sport[Category[@CategoryId='48']"

Would be one way.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39
  • With "/LiveScoreData/Sport[Category[@CategoryId='48']]" is returned empty array. With "//Sport[Category[@CategoryId='48']]" is returned Sport node, and both Category nodes (48 i 49), but only categoryid 48 is required. And thank you for prompt answer. – HeyHo Aug 21 '13 at 15:46
  • 1
    Xpath selects nodes, it doesn't manipulate them. once you have it, you could remove the ones with the id's you don't want – Tony Hopkinson Aug 21 '13 at 16:18
0

One easy answer which comes to mind is (How do I select multiple nodesets):

$data = $xml->xpath('//Category[@CategoryId="48"] | //Sport[Category[@CategoryId="48"]]');

However, I'd drop SimpleXML for this case and do this:

 $dom = new DOMDocument();
 $dom->load("livescore_full.xml");
 $xpath = new DOMXPath($dom);
 $category = $xpath->query('//Category[@CategoryId="48"]')->item(0);
 //then sport is just it's parentNode:
 $sport = $category->parentNode; 

 //removing all other cats:
 $dom = new DOMDocument();
 $dom->load("livescore_full.xml");
 $xpath = new DOMXPath($dom);

 $categories = $xpath->query('//Sport[Category[@CategoryId="48"]]/Category[@CategoryId!="48"]');
 while($othercat = $categories->item(0)){
     $othercat->parentNode->removeChild($othercat);
 }
Community
  • 1
  • 1
Wrikken
  • 69,272
  • 8
  • 97
  • 136
  • Selecting multiple nodes is not the solution I'm looking for. I'm try to get result like this (array of objects in that structure): ` Soccer Argentina Primera Division, Torneo Inicial ` Thank you for your answer. – HeyHo Aug 21 '13 at 17:15
  • So, with the wording _". I want to select one specific Category node and his parent node (Sport) with one expression"_ you meant _"I want a sports node with only 1 category"_... which is an entirely different thing. Coming up... – Wrikken Aug 21 '13 at 17:19
  • Yes, that is true, sorry. But I do not know SportId, only CategoryId when selecting node. – HeyHo Aug 21 '13 at 17:32