如何访问从外部 XML 接收到的 'Dublin Core' 命名空间中的信息?

How can I access the infomation in the 'Dublin Core' namespace received from external XML?


在最后一天,我在 PHP 中进行了一些 XML 的解析。我使用外部服务通过 XML 为我提供基于 ISBN 作为搜索词的书籍信息(德国国家图书馆提供的一项服务,要求在请求中包含一个私人令牌(这不是问题的原因,我已经检查过了) -> https://www.dnb.de/EN/Professionell/Metadatendienste/Datenbezug/SRU/sru_node.html | 我还检查了 php.ini) 中是否启用了 'allow_url_fopen' .

现在,我的问题是我使用的任何 XML 解析方法都没有显示和访问我在简单 XML 元素对象中使用的必要书籍信息(见结果第二个 'echo' 来自我下面的代码 screenshot). If I first pull the XML as a string, the information is visible and accesible (see the result of the first 'echo' from my code below in this screenshot)。目标是能够根据元素名称(dc:title、dc:creator、dc:publisher、dc:date 等)分别访问有关书籍的信息。在我当前的代码中,这是不可能的,因为 PHP 会告诉我:"Warning: main(): Node no longer exists" when 运行 through the 'foreach' loop.

我已经看过几个关于简单 XML 元素对象中命名空间问题的 Stack Overflow 帖子,但我无法针对我在这里面临的问题调整那里提出的解决方案。
我希望有人能帮我解决这个问题并指出一个解决方案,这样我就可以访问 XML.

的 'dc' 命名空间中的信息

这是非常简短的PHP-我目前使用的代码:

$request = file_get_contents("http://externalXML.com"); //URL was replaced
echo "<pre>"; print_r($request); echo "</pre>"; 
$xml = simplexml_load_string($request);
echo "<pre>"; print_r($xml); echo "</pre>"; 
foreach ($xml->records->record->recordData->dc->children() as $child) {
    echo "Inhalt: " . $child . "<br>";
}

这是 XML 的内容(因为我一直在寻找唯一的 ISBN(参见 'query'-元素),只能有一个或一个结果,但不会更多):

<searchRetrieveResponse>
<version>1.1</version>
<numberOfRecords>1</numberOfRecords>
<records>
    <record>
    <recordSchema>oai_dc</recordSchema>
    <recordPacking>xml</recordPacking>
    <recordData>
        <dc>
            <dc:title>1968 : Worauf wir stolz sein dürfen / Gretchen Dutschke</dc:title>
            <dc:creator>Dutschke, Gretchen [Verfasser]</dc:creator>
            <dc:publisher>Hamburg : Sven Murmann Verlagsgesellschaft mbH</dc:publisher>
            <dc:date>2018</dc:date>
            <dc:language>ger</dc:language>
            <dc:identifier xsi:type="tel:URN">urn:nbn:de:101:1-201803147211</dc:identifier>
            <dc:identifier xsi:type="tel:URL">http://nbn-resolving.de/urn:nbn:de:101:1-201803147211</dc:identifier>
            <dc:identifier xsi:type="tel:ISBN">978-3-96196-007-1</dc:identifier>
            <dc:identifier xsi:type="tel:URL">http://d-nb.info/1154519600/34</dc:identifier>
            <dc:identifier xsi:type="tel:URL">https://www.kursbuch.online</dc:identifier>
            <dc:identifier xsi:type="dnb:IDN">1154519600</dc:identifier>
            <dc:subject>300 Sozialwissenschaften, Soziologie, Anthropologie</dc:subject>
            <dc:type>Online-Ressource</dc:type>
            <dc:relation>http://d-nb.info/1144647959</dc:relation>
        </dc>
    </recordData>
    <recordPosition>1</recordPosition>
    </record>
</records>
<nextRecordPosition>2</nextRecordPosition>
<echoedSearchRetrieveRequest>
<version>1.1</version>
<query>"9783961960071"</query>
<xQuery xsi:nil="true"/>
</echoedSearchRetrieveRequest>
</searchRetrieveResponse>

干杯,蒂莫

注意:如果缺少声明只是问题中的错误,则应将其标记为

的重复项

如果 XML 实际上如问题所示,则它是无效的 - 没有命名空间前缀 dcxsi 的声明。如果您检查 PHP 日志,或打开 display_errors,您将在每次解析 XML 时看到许多警告。

要解决这个损坏的 XML,您可以将响应包装在定义命名空间的额外根元素中,从而生成有效的 XML.

// Define your namespace URIs somewhere, for reference
// Since you're faking them, they could be anything you like, but in case the XML
//  is fixed in future, you might as well use the values that were probably intended
define('XMLNS_DUBLIN_CORE', 'http://purl.org/dc/elements/1.1/');
define('XMLNS_XSD_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance');

// Add a wrapper with the missing namespace declarations around the whole document
$request = '<dummy xmlns:dc="' . XMLNS_DUBLIN_CORE . '" xmlns:xsi="' . XMLNS_XSD_INSTANCE . '">'
    . $request
    . "</dummy>";

// Parse the now-valid XML
$xml = simplexml_load_string($request);

// Pop the wrapper off to get the original root element
$xml = $xml->children()[0];

// Proceed as though the document had been defined properly
echo $xml->records->record->recordData->dc->children(XMLNS_DUBLIN_CORE)->title;