2013-04-15 3 views
0

-доступа PHP SimpleXML с пространствами имен

Привет всем,

Я пытаюсь получить доступ к данным в файле 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.

Мне нужно получить доступ к данным, как постоянного тока: дата постоянного тока: источник и т.д.

Любой любые идеи?

С наилучшими пожеланиями, Tim

- ОБНОВЛЕНИЕ -

Я сейчас пытаюсь это:

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; 
} 
+0

возможно дубликат http://stackoverflow.com/questions/6578832/how-to-convert-xml-into-array-in-php –

+0

Где вы застряли? Существующие запросы, такие как [Как обработать XML, содержащий пользовательские пространства имен, используя SimpleXML?] (Http://stackoverflow.com/q/1133897/2261774) или [Как получить доступ к элементу, например, с помощью simplexml?] (Http: // stackoverflow .com/q/1307459/2261774) Не полезно? –

+0

Я могу получить доступ к oai_dc (или, я думаю, могу), используя http://www.sitepoint.com/simplexml-and-namespaces/, но я не могу получить доступ к этому пространству имен. –

ответ

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');, чтобы показать, какой элемент (ы), в настоящее время, пересекающий в.

+0

Это было! Большое спасибо ;-) –

+0

У меня была такая же проблема, спасибо большое за публикацию этого решения. Сэкономил мне много времени! :) –

+0

Моя проблема заключается в том, что я извлекаю URL-адреса пространства имен из атрибутов заголовка. Но это не работает. Я попробовал пример отсюда, но это не помогло: http://php.net/manual/en/simplexmlelement.attributes.php –

0

Я думаю this является то, что вы ищете. Надеюсь, что это помогает;)

+0

Эй, Хулио, я пробовал это, но я думаю, потому что это пространство имен в пространстве имен, в котором это работает. –

+0

@TimHanssen: Нет, это не должно вас беспокоить. Вам просто нужно сделать это снова - с несколькими пространствами имен. –

+0

Так я попытался с помощью Еогеаспа ($ XML-> ListRecords как $ записи) { \t Еогеаспа ($ записывает как $ записи) \t { \t \t $ данных = $ Запись-> дети («HTTP: // WWW .openarchives.org/OAI/2.0/oai_dc/'); \t \t $ rows = $ data-> children ('http://purl.org/dc/elements/1.1/'); \t \t echo $ rows-> date; \t \t break; \t} \t break; } Я получил ошибку: Внимание: main(): Узел больше не существует –

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 

    ) 

) 
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); 
} 
Смежные вопросы