【问题标题】:How to Get a Sub-String of an XML String Using PHP如何使用 PHP 获取 XML 字符串的子字符串
【发布时间】:2017-01-14 13:27:02
【问题描述】:

所以我有一个 XML 字符串:

http://localhost:8888/?purp=oclcn&xml=<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<record xmlns="http://www.loc.gov/MARC21/slim">
    <leader>00000cam a2200000 a 4500</leader>
    <controlfield tag="001">33333502</controlfield>
    <controlfield tag="008">951010s1996    vtua     b    001 0 eng  </controlfield>
    <datafield ind1=" " ind2=" " tag="010">
      <subfield code="a">   95045582 </subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="020">
      <subfield code="a">1858983274</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="020">
      <subfield code="a">9781858983271</subfield>
    </datafield>
    <datafield ind1="0" ind2="0" tag="245">
      <subfield code="a">Economic sociology /</subfield>
      <subfield code="c">edited by Richard Swedberg.</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="260">
      <subfield code="a">Cheltenham, Glos, UK ;</subfield>
      <subfield code="a">Brookfield, Vt., US :</subfield>
      <subfield code="b">E. Elgar Pub. Co.,</subfield>
      <subfield code="c">©1996.</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="300">
      <subfield code="a">xv, 574 pages :</subfield>
      <subfield code="b">illustrations ;</subfield>
      <subfield code="c">25 cm.</subfield>
    </datafield>
    <datafield ind1="1" ind2=" " tag="490">
      <subfield code="a">The international library of critical writings in sociology ;</subfield>
      <subfield code="v">5</subfield>
    </datafield>
    <datafield ind1="1" ind2=" " tag="490">
      <subfield code="a">An Elgar reference collection</subfield>
    </datafield>
    <datafield ind1=" " ind2=" " tag="500">
      <subfield code="a">A collection of journal articles previously published between 1940-1994.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Economics</subfield>
      <subfield code="x">Sociological aspects.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Sociology.</subfield>
    </datafield>
    <datafield ind1=" " ind2="0" tag="650">
      <subfield code="a">Economics.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Économie politique</subfield>
      <subfield code="x">Aspect sociologique.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Sociologie.</subfield>
    </datafield>
    <datafield ind1=" " ind2="6" tag="650">
      <subfield code="a">Économie politique.</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Economics.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst00902116</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Economics</subfield>
      <subfield code="x">Sociological aspects.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst00902213</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Sociology.</subfield>
      <subfield code="2">fast</subfield>
      <subfield code="0">(OCoLC)fst01123875</subfield>
    </datafield>
    <datafield ind1="1" ind2="7" tag="650">
      <subfield code="a">Economische sociologie.</subfield>
      <subfield code="2">gtt</subfield>
    </datafield>
    <datafield ind1=" " ind2="7" tag="650">
      <subfield code="a">Sociologie économique.</subfield>
      <subfield code="2">ram</subfield>
    </datafield>
  </record>

如您所见,XML 嵌入了元素/标签等。

我想使用 Xpath 和 PHP 检索最后一个标签,但仍将其作为字符串(而不是数组或对象)返回(并且还包括子标签/子标签)。我该怎么办?

【问题讨论】:

    标签: php xml xpath


    【解决方案1】:

    http://php.net/manual/de/domdocument.savexml.php,可以调用$doc-&gt;saveXML($node)方法将DOM节点序列化为字符串。因此选择 DOM 元素(或一般的节点),然后在传入所选节点的文档上调用该方法以获取该节点的 XML 字符串表示:

    $xml = <<<EOD
    <record xmlns="http://www.loc.gov/MARC21/slim">
        <leader>00000cam a2200000 a 4500</leader>
        <controlfield tag="001">33333502</controlfield>
        <controlfield tag="008">951010s1996    vtua     b    001 0 eng  </controlfield>
        <datafield ind1=" " ind2=" " tag="010">
          <subfield code="a">   95045582 </subfield>
        </datafield>
        <datafield ind1=" " ind2=" " tag="020">
          <subfield code="a">1858983274</subfield>
        </datafield>
        <datafield ind1=" " ind2=" " tag="020">
          <subfield code="a">9781858983271</subfield>
        </datafield>
        <datafield ind1="0" ind2="0" tag="245">
          <subfield code="a">Economic sociology /</subfield>
          <subfield code="c">edited by Richard Swedberg.</subfield>
        </datafield>
        <datafield ind1=" " ind2=" " tag="260">
          <subfield code="a">Cheltenham, Glos, UK ;</subfield>
          <subfield code="a">Brookfield, Vt., US :</subfield>
          <subfield code="b">E. Elgar Pub. Co.,</subfield>
          <subfield code="c">©1996.</subfield>
        </datafield>
        <datafield ind1=" " ind2=" " tag="300">
          <subfield code="a">xv, 574 pages :</subfield>
          <subfield code="b">illustrations ;</subfield>
          <subfield code="c">25 cm.</subfield>
        </datafield>
        <datafield ind1="1" ind2=" " tag="490">
          <subfield code="a">The international library of critical writings in sociology ;</subfield>
          <subfield code="v">5</subfield>
        </datafield>
        <datafield ind1="1" ind2=" " tag="490">
          <subfield code="a">An Elgar reference collection</subfield>
        </datafield>
        <datafield ind1=" " ind2=" " tag="500">
          <subfield code="a">A collection of journal articles previously published between 1940-1994.</subfield>
        </datafield>
        <datafield ind1=" " ind2="0" tag="650">
          <subfield code="a">Economics</subfield>
          <subfield code="x">Sociological aspects.</subfield>
        </datafield>
        <datafield ind1=" " ind2="0" tag="650">
          <subfield code="a">Sociology.</subfield>
        </datafield>
        <datafield ind1=" " ind2="0" tag="650">
          <subfield code="a">Economics.</subfield>
        </datafield>
        <datafield ind1=" " ind2="6" tag="650">
          <subfield code="a">Économie politique</subfield>
          <subfield code="x">Aspect sociologique.</subfield>
        </datafield>
        <datafield ind1=" " ind2="6" tag="650">
          <subfield code="a">Sociologie.</subfield>
        </datafield>
        <datafield ind1=" " ind2="6" tag="650">
          <subfield code="a">Économie politique.</subfield>
        </datafield>
        <datafield ind1=" " ind2="7" tag="650">
          <subfield code="a">Economics.</subfield>
          <subfield code="2">fast</subfield>
          <subfield code="0">(OCoLC)fst00902116</subfield>
        </datafield>
        <datafield ind1=" " ind2="7" tag="650">
          <subfield code="a">Economics</subfield>
          <subfield code="x">Sociological aspects.</subfield>
          <subfield code="2">fast</subfield>
          <subfield code="0">(OCoLC)fst00902213</subfield>
        </datafield>
        <datafield ind1=" " ind2="7" tag="650">
          <subfield code="a">Sociology.</subfield>
          <subfield code="2">fast</subfield>
          <subfield code="0">(OCoLC)fst01123875</subfield>
        </datafield>
        <datafield ind1="1" ind2="7" tag="650">
          <subfield code="a">Economische sociologie.</subfield>
          <subfield code="2">gtt</subfield>
        </datafield>
        <datafield ind1=" " ind2="7" tag="650">
          <subfield code="a">Sociologie économique.</subfield>
          <subfield code="2">ram</subfield>
        </datafield>
      </record>
    
    EOD;
    
    $doc = new DOMDocument();
    $doc->loadXML($xml);
    
    $elements = $doc->getElementsByTagNameNS('*', 'datafield');
    $lastElement = $elements[$elements->length - 1];
    
    echo $doc->saveXML($lastElement);
    

    使用 XPath 不会改变关于序列化节点的任何内容,这里是相同的示例,但使用 XPath 表达式选择最后一个数据字段元素:

    $doc = new DOMDocument();
    $doc->loadXML($xml);
    
    $xpath = new DOMXPath($doc);
    $xpath->registerNamespace('df', $doc->documentElement->namespaceURI);
    
    
    $lastElement = $xpath->query('(//df:datafield)[last()]')[0];
    
    echo $doc->saveXML($lastElement);
    

    【讨论】:

    • 您的解决方案没有使用 XPath。与 XPath 不同,因为使用 DOMXPath,返回一个 DOMNodeList,而后者又返回 DOMElement(而不是 DOMDocument),它没有 saveXML 方法。
    • 好吧,如果你有一个 DOMElement,你也有一个拥有的 DOMDocument,然后你可以调用 $doc-saveXML($domElementNode),你拥有的节点是使用 getElementsByTagName 还是使用 XPath 或否则创建,如果您想序列化它,您可以按照我的回答第一段中的说明进行操作。使用 XPath 选择节点根本不会改变这种方法。
    • 如果当前上下文中没有文档,可以使用DOMNode::$ownerDocument属性$node-&gt;ownerDocument-&gt;saveXml($node);
    【解决方案2】:

    大概你要找的是

    if (($xml = simplexml_load_string($xml_string)) !== FALSE) {
        $xml->registerXPathNamespace('marc', 'http://www.loc.gov/MARC21/slim');
    
        // Retrieve the last "datafield" element
        $results = $xml->xpath('/marc:record/marc:datafield[last()]');
        if ($results !== FALSE and ($datafield = reset($results)) !== FALSE) {
            // Process the element, or simply output it with:
            echo $datafield->saveXML();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-21
      • 1970-01-01
      • 2011-11-05
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 2017-02-22
      • 2015-07-07
      相关资源
      最近更新 更多