【问题标题】:Loading a Search and Retrieve via URL (SRU) in php with simplexml_load_string returns an empty object使用 simplexml_load_string 在 php 中通过 URL (SRU) 加载搜索和检索返回一个空对象
【发布时间】:2018-07-08 01:41:54
【问题描述】:

我正在尝试使用 Search and Retrieve via URL (SRU) 从库 api 加载搜索结果:https://data.norge.no/data/bibsys/bibsys-bibliotekbase-bibliografiske-data-sru

如果您在那里看到搜索结果链接,它看起来很像 XML,但是当我尝试像以前使用下面的代码使用 xml 时,它只返回一个空对象,

SimpleXMLElement {#546}

这是怎么回事?

我在 laravel 项目中的 php 函数:

public function bokId($bokid) {
    $apiUrl = "http://sru.bibsys.no/search/biblio?version=1.2&operation=searchRetrieve&startRecord=1&maximumRecords=10&query=ibsen&recordSchema=marcxchange";
    $filename = "bok.xml";
    $xmlfile = file_get_contents($apiUrl);
    file_put_contents($filename, $xmlfile); // xml file is saved.
    $fileXml = simplexml_load_string($xmlfile);
    dd($fileXml);
}

如果我这样做:

 dd($xmlfile);

相反,它会像这样回显:

让我很困惑,我无法使用对象。我现在的代码以前工作得很好。

【问题讨论】:

    标签: php xml xml-parsing


    【解决方案1】:

    可能是您提供的数据格式发生了变化,但数据仍然存在,您仍然可以使用它。使用dd() 之类的主要问题是它不能很好地与 SimpleXMLElements 配合使用,它往往对你想查看哪些数据有自己的想法。

    在这种情况下,命名空间是常见的问题。但是,如果您查看以下代码,您会看到一种从特定命名空间获取数据的快速方法,然后您可以像往常一样轻松访问该命名空间。在这段代码中,我使用->children("srw", true) 表示获取命名空间 srw 中的所有子元素(第二个参数表示这是前缀而不是 URL)...

    $apiUrl = "http://sru.bibsys.no/search/biblio?version=1.2&operation=searchRetrieve&startRecord=1&maximumRecords=10&query=ibsen&recordSchema=marcxchange";
    $filename = "bok.xml";
    $xmlfile = file_get_contents($apiUrl);
    file_put_contents($filename, $xmlfile); // xml file is saved.
    $fileXml = simplexml_load_string($xmlfile);
    
    foreach ( $fileXml->children("srw", true)->records->record as $record)  {
        echo "recordIdentifier=".$record->recordIdentifier.PHP_EOL;
    }
    

    这输出...

    recordIdentifier=792012771
    recordIdentifier=941956423
    recordIdentifier=941956466
    recordIdentifier=950546232
    recordIdentifier=802109055
    recordIdentifier=910941041
    recordIdentifier=940589451
    recordIdentifier=951721941
    recordIdentifier=080703852
    recordIdentifier=011800283
    

    由于我不确定您要检索哪些数据作为标题,因此我只是想展示在您拥有一系列可能性时如何获取数据的想法。在此示例中,我使用 XPath 查看每个 <srw:record> 元素并找到 <marc:datafield tag="100"...> 元素和 <marc:subfield code="a"> 元素。这是使用//marc:datafield[@tag='100']/marc:subfield[@code='a'] 完成的。您可能需要将@tag= 位调整为您之后的数据字段,并将@code= 调整为指向您之后的子字段。

    $fileXml = simplexml_load_string($xmlfile);
    $fileXml->registerXPathNamespace("marc","info:lc/xmlns/marcxchange-v1");
    
    foreach ( $fileXml->children("srw", true)->records->record as $record)  {
        echo "recordIdentifier=".$record->recordIdentifier.PHP_EOL;
    
        $data = $record->xpath("//marc:datafield[@tag='100']/marc:subfield[@code='a']");
        $subData=$data[0]->children("marc", true);
        echo "Data=".(string)$data[0].PHP_EOL;
    }
    

    【讨论】:

    • 非常感谢您的工作解决方案和解释!
    • Nigel,我想知道您是否也可以帮助我从实际记录中获取数据。就像一个如何获取第一条记录的字符串书名的示例。在您的帖子之后我已经尝试了很多,并搜索了类似的代码,但我没有进一步了解。 (我尝试过的东西hastebin.com/bumuqimaba.pl)。我觉得我非常接近实际使用这个 api,但我需要帮助。将不胜感激。
    • 我添加了一个示例,不完全确定您所追求的字段,但希望对您有所帮助。
    • 真的很有帮助,非常感谢,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 2018-02-18
    • 1970-01-01
    相关资源
    最近更新 更多