Retrieving a subset of XML nodes with PHP

前端 未结 5 1698
无人及你
无人及你 2020-12-20 00:48

Using PHP, how do I get an entire subset of nodes from an XML document? I can retrieve something like:


相关标签:
5条回答
  • 2020-12-20 01:05

    See http://www.php.net/manual/en/domdocument.getelementsbytagname.php

    0 讨论(0)
  • 2020-12-20 01:07

    Use DOM and XPath. Xpath allows you to select nodes (and values) from an XML DOM.

    $dom = new DOMDocument();
    $dom->loadXml($xml);
    $xpath = new DOMXpath($dom);
    
    $result = '';
    foreach ($xpath->evaluate('/people/certain') as $node) {
      $result .= $dom->saveXml($node);
    }
    
    echo $result;
    

    Demo: https://eval.in/162149

    DOMDocument::saveXml() has a context argument. If provided it saves that node as XML. Much like outerXml(). PHP is able to register your own classes for the DOM nodes, too. So it is even possible to add an outerXML() function to element nodes.

    class MyDomElement extends DOMElement {
      public function outerXml() {
        return $this->ownerDocument->saveXml($this);
      }
    }
    
    class MyDomDocument extends DOMDocument {
      public function __construct($version = '1.0', $encoding = 'utf-8') {
        parent::__construct($version, $encoding);
        $this->registerNodeClass('DOMElement', 'MyDomElement');
      }
    }
    
    $dom = new MyDomDocument();
    $dom->loadXml($xml);
    $xpath = new DOMXpath($dom);
    
    $result = '';
    foreach ($xpath->evaluate('/people/certain') as $node) {
      $result .= $node->outerXml();
    }
    
    echo $result;
    

    Demo: https://eval.in/162157

    0 讨论(0)
  • 2020-12-20 01:08

    You could use DOMDocument.GetElementsByTagName or you could:

    Use XPath?

    <?php
    $xml = simplexml_load_file("test.xml");
    
    $result = $xml->xpath("//certain");
    
    print_r($result);
    ?>
    
    0 讨论(0)
  • 2020-12-20 01:10

    The answer would be to use XPath.

    $people = simplexml_load_string(
        '<?xml version="1.0" encoding="utf-8"?>
        <people>
          <certain>
            <name>Jane Doe</name>
            <age>21</age>
          </certain>
          <certain>
            <name>John Smith</name>
            <age>34</age>
          </certain>
        </people>'
    );
    
    // get all <certain/> nodes
    $people->xpath('//certain');
    
    // get all <certain/> nodes whose <name/> is "John Smith"
    print_r($people->xpath('//certain[name = "John Smith"]'));
    
    // get all <certain/> nodes whose <age/> child's value is greater than 21
    print_r($people->xpath('//certain[age > 21]'));
    

    Take 2

    So apparently you want to copy some nodes from a document into another document? SimpleXML doesn't support that. DOM has methods for that but they're kind of annoying to use. Which one are you using? Here's what I use: SimpleDOM. In fact, it's really SimpleXML augmented with DOM's methods.

    include 'SimpleDOM.php';
    $results = simpledom_load_string('<results/>');
    
    foreach ($people->xpath('//certain') as $certain)
    {
        $results->appendChild($certain);
    }
    

    That routine finds all <certain/> node via XPath, then appends them to the new document.

    0 讨论(0)
  • 2020-12-20 01:15

    The answer turned out to be a combination of the xpath suggestion and outputting with asXML().

    Using the example given by Josh Davis:

    $people = simplexml_load_string(
          <?xml version="1.0" encoding="utf-8"?>
            <people>
              <certain>
                <name>Jane Doe</name>
                <age>21</age>
              </certain>
              <certain>
                <name>John Smith</name>
                <age>34</age>
              </certain>
            </people>'
        );
    
        // get all <certain/> nodes
        $nodes = $people->xpath('/people/certain');
    
        foreach ( $nodes as $node ) {
          $result .= $node->asXML()."\n";
        }
        echo $result;
    
    0 讨论(0)
提交回复
热议问题