Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
703 views
in Technique[技术] by (71.8m points)

php - Selecting parent nodes with XMLReader

I had to rewrite part of a programme to use XMLReader to select parts of an XML file for processing.

Take this simplified XML as an example:

<odds>
    <sport>
        <region>
            <group>
                <event name="English Championship 2014-15" eventid="781016.1">
                    <bet name="Kazanan" betid="12377108.1">
                        <selection selectionid="52411062.1"/>
                        </selection>
                    </bet>
                </event>
            </group>
        </region>
    </sport>
</odds> 

This call to xpath():

$bets = $xml->xpath(
    "//odds/sport/region/group/event/bet/selection[contains(@selectionid,'".$selectionToFind."')]/.."
    );

would select the whole <bet> node and its children (<selection> nodes).

My code, however, would select only one <selection> node with a given selectionid:

$reader = new XMLReader;
$reader->open('file.xml');

while($reader->read()) {
    $event = $reader->getAttribute($value); 

    if ($event == 781016.1 ) {
        $node = new SimpleXMLElement($reader->readOuterXML());
        var_dump($node);
        break;
    }
}

How can replicate the behaviour of xpath() with XMLReader so that I select the <bet> node and its children and not only one <selection> child?

I guess the question boils down to: Can I select the whole parent node <bet> by the attribute value of a child, e.g. <selection selectionid="[some_value]">?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

[Ignore the SimpleXML solution and look down at the XMLReader one]

I would suggest using the SimpleXMLElement::xpath method.

http://php.net/manual/en/simplexmlelement.xpath.php

$xml = new SimpleXMLElement($xml_string);

/* Search for <a><b><c> */
$result = $xml->xpath("/odds/sport/region/group/event/bet");

$result will contain all children of 'bet' note.

// XMLReader solution **********************

$reader = new XMLReader;
$reader->open('file.xml');
$parent_element = null;

while($reader->read()) {
    $selectionid = $reader->getAttribute('selectionid'); 

    if ($selectionid == '52411062.1' ) {
        // use the parent of the node with attribute 'selectionid' = '52411062.1'
        $node = $parent_element;
        var_dump($node);
        break;
    }
    elseif ($reader->name === 'bet') { )
    {
        // store parent element
        $parent_element = new SimpleXMLElement($reader->readOuterXML());
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...