通过PHP检索XML页面的元素

时间:2010-08-01 20:34:40

标签: php xml

我正试图围绕PHP和XML。

我正在尝试做点什么:

我正在通过cURL检索XML文档(还尝试了各种PHP XML库参数,例如XMLReader::open($url)等。检索方法并不重要;我可以并且已经使这部分工作了。

问题是在检索到的页面上解析XML。

以下是XML的示例:

http://z3950.loc.gov:7090/voyager?version=1.1&operation=searchRetrieve&query=9780471615156&maximumRecords=1&recordPacking=xml&recordSchema=marcxml

我需要从该页面获取的是电话号码;

<datafield tag="060" ind1=" " ind2=" ">
  <subfield code="a">WM 173.6 R823m</subfield>
</datafield>

作者;

<datafield tag="100" ind1="1" ind2=" ">
  <subfield code="a">Ross, Colin A.</subfield>
</datafield>

和标题信息;

<datafield tag="245" ind1="1" ind2="0">
  <subfield code="a">Multiple personality disorder :</subfield>
  <subfield code="b">diagnosis, clinical features, and treatment /</subfield>
  <subfield code="c">Colin A. Ross.</subfield>
</datafield>

看起来很简单。然而,对于我的生活,我似乎无法获得任何内置的PHP函数来使用XML(因为我做错了)。

以下是我尝试过的一个例子:

//xml file retrieved via curl and saved to folder
$file="9780471615156.xml";

$xml = simplexml_load_file($file);

echo $xml->getName();//returns searchRetrieveResponse

foreach($xml->searchRetrieveResponse[0]->attributes() as $a => $b){
  echo $a,'="',$b,"\"</br>";//nothing
 }

foreach ($xml->searchRetrieveResponse[0]->children() as $child){
  echo "Child node: " . $child . "<br />";//nothing
}

它返回第一个节点的名称,但我不能让它更深入。

注意:我正在运行PHP 5 +

3 个答案:

答案 0 :(得分:3)

鉴于您希望解析MARCXML,我建议您使用File_MARC PEAR package。要生成类似于您希望执行的操作,代码看起来大致如下:

<?php

require_once('File/MARCXML.php');
$file="9780471615156.xml";
$record = new File_MARCXML($file);
echo "  call number: \n";
echo "   " . $record->getField('060')['a'];
echo "  author: \n";
echo "   " . $record->getField('100')['a'];
echo "  title: \n";
echo "   " . $record->getField('245')->formatField();

答案 1 :(得分:2)

xml_parse_into_struct()可能没什么问题。但是,由于已经声明使用SimpleXML无法做到这一点:

<?php 
$file="http://z3950.loc.gov:7090/voyager?version=1.1&operation=searchRetrieve&query=9780471615156&maximumRecords=1&recordPacking=xml&recordSchema=marcxml";
$xml = simplexml_load_file($file);
$xml->registerXPathNamespace('foo', 'http://www.loc.gov/MARC21/slim');

foreach( $xml->xpath('//foo:record') as $record ) {
  echo "record: \n";
  $record->registerXPathNamespace('foo', 'http://www.loc.gov/MARC21/slim');
  foreach( $record->xpath('foo:datafield[@tag="060" or @tag="100" or @tag="245"]') as $datafield ) {
    switch($datafield['tag']) {
      case '060':
        echo "  call number: \n";
        break;
      case '100':
        echo "author: \n";
        break;
      case '245':
        echo "title : \n";
        break;
    }
    $datafield->registerXPathNamespace('foo', 'http://www.loc.gov/MARC21/slim');
    foreach( $datafield->xpath('foo:subfield') as $sf ) {
      echo '   ', $sf['code'] . ': ' . $sf . "\n";
    }    
  }
}

打印

record: 
  call number: 
   a: WM 173.6 R823m
author: 
   a: Ross, Colin A.
title : 
   a: Multiple personality disorder :
   b: diagnosis, clinical features, and treatment /
   c: Colin A. Ross.

你必须为每个后续的SimpleXMLElement一次又一次地注册命名空间有点烦人......但是无论如何它都可以使用SimpleXML; - )

另请参阅:http://docs.php.net/simplexmlelement.registerXPathNamespacehttp://www.w3.org/TR/xpath/

答案 2 :(得分:1)

据我所知,simpleXML无法读取此XML。试试下面的例子,它会列出一个数组,你可以通过比较你正在寻找的键/值来轻松地循环并找到你需要的东西。

// load XML into string here
// $string = ????;
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $string, $object, $index);

echo '<pre>';
print_r($object);
// print_r($index);
echo '</pre>';