0

-

大家好,

我正在尝试访问 XML 文件中的数据:

<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi-    namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/     http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd";>
 <responseDate>2013-04-15T12:14:31Z</responseDate>
 <ListRecords>
 <record>
 <header>
 <identifier>
 a1b31ab2-9efe-11df-9922-efbb156aa6c1:01442b82-59a4-627e-800f-c63de74fc109
 </identifier>
 <datestamp>2012-08-16T14:42:52Z</datestamp>
 </header>
 <metadata>
 <oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd";>
 <dc:description>...</dc:description>
 <dc:date>1921</dc:date>
 <dc:identifier>K11510</dc:identifier>
 <dc:source>Waterschap Vallei & Eem</dc:source>
 <dc:source>...</dc:source>
 <dc:source>610</dc:source>
 <dc:coverage>Bunschoten</dc:coverage>
 <dc:coverage>Veendijk</dc:coverage>
 <dc:coverage>Spakenburg</dc:coverage>
 </oai_dc:dc>
 </metadata>
 <about>...</about>
 </record>

这是 XML 的一个示例。

我需要访问 dc:date dc:source 等数据。

有人有什么想法吗?

最好的问候,蒂姆

- 更新 -

我现在正在尝试这个:

foreach( $xml->ListRecords as $records )
{
foreach( $records AS $record )
{

    $data = $record->children( 'http://www.openarchives.org/OAI/2.0/oai_dc/' );

    $rows = $data->children( 'http://purl.org/dc/elements/1.1/' );

    echo $rows->date;


    break;
}

break;
}
4

4 回答 4

2

您拥有位于不同 XML 名称空间中的嵌套元素。具体来说,您还涉及两个额外的命名空间:

$nsUriOaiDc = 'http://www.openarchives.org/OAI/2.0/oai_dc/';
$nsUriDc    = 'http://purl.org/dc/elements/1.1/';

第一个用于<oai_dc:dc>包含第二个 * <dc:*>* 元素之类的元素<dc:description>,依此类推。这些是您正在寻找的元素。

在您的代码中,您已经很好地了解了它是如何工作的:

$data = $record->children( 'http://www.openarchives.org/OAI/2.0/oai_dc/' );

$rows = $data->children( 'http://purl.org/dc/elements/1.1/' );

但是有一个错误:$data孩子不是 的孩子,$record而是 的孩子$record->metadata

您也不需要将两个foreach相互嵌套。代码示例:

$nsUriOaiDc = 'http://www.openarchives.org/OAI/2.0/oai_dc/';

$nsUriDc    = 'http://purl.org/dc/elements/1.1/';

$records = $xml->ListRecords->record;

foreach ($records as $record)
{    
    $data = $record->metadata->children($nsUriOaiDc);

    $rows = $data->children($nsUriDc);

    echo $rows->date;

    break;
}

/** output: 1921 **/

如果您遇到此类问题,您可以使用$record->asXML('php://output');来显示您当前正在遍历的元素。

于 2013-04-15T11:25:43.343 回答
0

我想就是你要找的。希望能帮助到你 ;)

于 2013-04-15T11:01:53.727 回答
0

使用 DomDocument 进行类似访问dc:date

  $STR='
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi-    namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/     http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd";>
 <responseDate>2013-04-15T12:14:31Z</responseDate>
 <ListRecords>
 <record>
 <header> <identifier> a1b31ab2-9efe-11df-9922-efbb156aa6c1:01442b82-59a4-627e-800f-c63de74fc109 </identifier>
<datestamp>2012-08-16T14:42:52Z</datestamp>
</header>
<metadata>
 <oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd";>
  <dc:description>...</dc:description>
  <dc:date>1921</dc:date>
  <dc:identifier>K11510</dc:identifier>
  <dc:source>Waterschap Vallei & Eem</dc:source>
  <dc:source>...</dc:source>
  <dc:source>610</dc:source>
  <dc:coverage>Bunschoten</dc:coverage>
  <dc:coverage>Veendijk</dc:coverage>
  <dc:coverage>Spakenburg</dc:coverage>
 </oai_dc:dc>
</metadata>
<about>...</about>
</record>';

  $dom= new DOMDocument; 
  $STR= str_replace("&", "&amp;", $STR);  // disguise &s going IN to loadXML() 
  // $dom->substituteEntities = true;  // collapse &s going OUT to transformToXML() 
  $dom->recover = TRUE;
  @$dom->loadHTML('<?xml encoding="UTF-8">' .$STR); 
  // dirty fix
  foreach ($dom->childNodes as $item)
  if ($item->nodeType == XML_PI_NODE)
      $dom->removeChild($item); // remove hack
  $dom->encoding = 'UTF-8'; // insert proper

  print_r($doc->getElementsByTagName('dc')->item(0)->getElementsByTagName('date')->item(0)->textContent);

输出:

 1921

或访问dc:source

 $source= $doc->getElementsByTagName('dc')->item(0)->getElementsByTagName('source');
 foreach($source as $value){
     echo $value->textContent."\n";
 }

输出:

Waterschap Vallei & Eem
...
610

或者给你数组

 $array=array();
 $source= $doc->getElementsByTagName('dc')->item(0)->getElementsByTagName("*");
 foreach($source as $value){

     $array[$value->localName][]=$value->textContent."\n";


 } 
 print_r($array);

输出:

 Array
(
   [description] => Array
    (
        [0] => ...

    )

   [date] => Array
    (
        [0] => 1921

    )

   [identifier] => Array
    (
        [0] => K11510

    )

   [source] => Array
    (
        [0] => Waterschap Vallei & Eem

        [1] => ...

        [2] => 610

    )

   [coverage] => Array
    (
        [0] => Bunschoten

        [1] => Veendijk

        [2] => Spakenburg

    )

)
于 2013-04-15T11:23:56.303 回答
0

使用 XPath 可以更直接地处理命名空间:

<?php

// load the XML into a DOM document
$doc = new DOMDocument;
$doc->load('oai-response.xml'); // or use $doc->loadXML($xml) for an XML string

// bind the DOM document to an XPath object
$xpath = new DOMXPath($doc);

// map all the XML namespaces to prefixes, for use in XPath queries
$xpath->registerNamespace('oai', 'http://www.openarchives.org/OAI/2.0/');
$xpath->registerNamespace('oai_dc', 'http://www.openarchives.org/OAI/2.0/oai_dc/');
$xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');

// identify each record using an XPath query
// collect data as either strings or arrays of strings
foreach ($xpath->query('oai:ListRecords/oai:record/oai:metadata/oai_dc:dc') as $item) {
    $data = array(
        'date' => $xpath->evaluate('string(dc:date)', $item), // $item is the context for this query
        'source' => array(),
    );

    foreach ($xpath->query('dc:source', $item) as $source) {
        $data['source'][] = $source->textContent;
    }

    print_r($data);
}
于 2013-08-29T13:32:39.560 回答