Php 如何访问从外部XML接收的“都柏林核心”命名空间中的信息?

Php 如何访问从外部XML接收的“都柏林核心”命名空间中的信息?,php,xml,xml-parsing,simplexml,dublin-core,Php,Xml,Xml Parsing,Simplexml,Dublin Core,最后一天,我在PHP中进行一些XML解析。我使用外部服务通过XML向我提供基于ISBN作为搜索词的书籍信息德国国家图书馆提供的服务要求在请求中包含私人令牌这不是问题的原因,我已经检查过->|并且还检查了php.ini中是否启用了“allow_url_fopen” 现在,我的问题是,无论我使用什么样的XML解析方法,我都无法在简单的XML元素对象中显示和访问所需的书籍信息。请参见下面代码中的第二个“echo”的结果。如果我首先以字符串的形式提取XML,则信息是可见的和可访问的。请参阅下面的本文中我

最后一天,我在PHP中进行一些XML解析。我使用外部服务通过XML向我提供基于ISBN作为搜索词的书籍信息德国国家图书馆提供的服务要求在请求中包含私人令牌这不是问题的原因,我已经检查过->|并且还检查了php.ini中是否启用了“allow_url_fopen”

现在,我的问题是,无论我使用什么样的XML解析方法,我都无法在简单的XML元素对象中显示和访问所需的书籍信息。请参见下面代码中的第二个“echo”的结果。如果我首先以字符串的形式提取XML,则信息是可见的和可访问的。请参阅下面的本文中我的代码中第一个“echo”的结果。我们的目标是能够分别基于元素名dc:title、dc:creator、dc:publisher、dc:date等访问有关书籍的信息。在我当前的代码中,这是不可能的,因为PHP会告诉我:警告:main:当运行“foreach”循环时,节点不再存在

我已经看过几篇关于简单XML元素对象中的名称空间问题的堆栈溢出文章,但是我无法针对我在这里遇到的问题调整那里提出的解决方案。 我希望有人能在这方面帮助我,并为我指出一个解决方案,这样我就可以访问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 see‘query’——元素,只能有一个结果,但不能有更多:

干杯,蒂莫注意:如果缺少的声明只是问题中的一个错误,那么应该将其标记为

如果XML实际上如问题所示,那么它是无效的——没有名称空间前缀dc和xsi的声明。如果您检查PHP日志,或者打开display_errors,那么每次解析XML时都会看到几十条警告

为了解决这个破碎的XML,您可以将响应封装在一个额外的根元素中,该根元素定义名称空间,从而生成有效的XML


XML格式不正确,因为没有dc前缀xmlns:dc的声明=http://purl.org/dc/elements/1.1/ 缺少。也许您可以将所有出现的dc:更改为,例如,dc-,这样它们就不会被解释为命名空间前缀。@mzjn您可以,但这会导致非常脆弱的代码,并且是不必要的,因为SimpleXML具有对XML名称空间的内置处理。我认为缺少xmlns属性正是发布前对示例进行裁剪的方式;否则,解析器会给出一个错误。@mzjn就像我说的,我认为这只是发布问题时的一个错误。然而,我显然错误地认为simplexml_load_string在这种情况下会返回false;它显然会发出警告,然后返回对象。即便如此,更好的解决方法还是操纵XML的根来定义名称空间-也许只是将其包装在一个新的根元素中-而不是试图替换其中的每一个事件而不损坏数据。@Timo您能否确认您发布的XML是否确实是您得到的,回复中没有提到xmlns?如果是这样,我将重新开放。但是,您可能可以了解很多关于响应来自何处的背景细节—a只需要XML块和PHP代码。
<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>
// 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;