1

I have this following segment of XML:

<?xml version="1.0" encoding="UTF-8"?>
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
   <version>1.1</version>
   <numberOfRecords>1</numberOfRecords>
   <records>
      <record>
     <recordSchema>MARC21-xml</recordSchema>
     <recordPacking>xml</recordPacking>
     <recordData>
        <record xmlns="http://www.loc.gov/MARC21/slim" type="Authority">
           <leader>00000nz  a2200000nc 4500</leader>
           <controlfield tag="001">040432386</controlfield>
           <controlfield tag="003">DE-101</controlfield>
           <controlfield tag="005">20180124053847.0</controlfield>
           <controlfield tag="008">880701n||azznnbabn           | ana    |c</controlfield>
           <datafield tag="024" ind1="7" ind2=" ">
          <subfield code="a">http://d-nb.info/gnd/4043238-5</subfield>
          <subfield code="2">uri</subfield>
           </datafield>
           <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="a">(DE-101)040432386</subfield>
           </datafield>
           <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="a">(DE-588)4043238-5</subfield>
           </datafield>
           <datafield tag="035" ind1=" " ind2=" ">
          <subfield code="z">(DE-588c)4043238-5</subfield>
          <subfield code="9">v:zg</subfield>
           </datafield>
           <datafield tag="040" ind1=" " ind2=" ">
          <subfield code="a">DE-101</subfield>
          <subfield code="9">r:DE-101</subfield>
          <subfield code="b">ger</subfield>
          <subfield code="d">9999</subfield>
           </datafield>
           <datafield tag="042" ind1=" " ind2=" ">
          <subfield code="a">gnd1</subfield>
           </datafield>
           <datafield tag="065" ind1=" " ind2=" ">
          <subfield code="a">13.3</subfield>
          <subfield code="2">sswd</subfield>
           </datafield>
           <datafield tag="075" ind1=" " ind2=" ">
          <subfield code="b">s</subfield>
          <subfield code="2">gndgen</subfield>
           </datafield>
           <datafield tag="075" ind1=" " ind2=" ">
          <subfield code="b">saz</subfield>
          <subfield code="2">gndspec</subfield>
           </datafield>
           <datafield tag="079" ind1=" " ind2=" ">
          <subfield code="a">g</subfield>
          <subfield code="q">s</subfield>
          <subfield code="u">w</subfield>
          <subfield code="u">o</subfield>
          <subfield code="u">z</subfield>
           </datafield>
           <datafield tag="083" ind1="0" ind2="4">
          <subfield code="a">751.45</subfield>
          <subfield code="9">d:3</subfield>
          <subfield code="9">t:2007-01-01</subfield>
          <subfield code="2">22/ger</subfield>
           </datafield>
           <datafield tag="150" ind1=" " ind2=" ">
          <subfield code="a">Ölmalerei</subfield>
           </datafield>
           <datafield tag="450" ind1=" " ind2=" ">
          <subfield code="a">Ölgemälde</subfield>
           </datafield>
           <datafield tag="550" ind1=" " ind2=" ">
          <subfield code="0">(DE-101)040372200</subfield>
          <subfield code="0">(DE-588)4037220-0</subfield>
          <subfield code="0">http://d-nb.info/gnd/4037220-0</subfield>
          <subfield code="a">Malerei</subfield>
          <subfield code="4">obal</subfield>
          <subfield code="4">http://d-nb.info/standards/elementset/gnd#broaderTermGeneral</subfield>
          <subfield code="w">r</subfield>
          <subfield code="i">Oberbegriff allgemein</subfield>
           </datafield>
           <datafield tag="670" ind1=" " ind2=" ">
          <subfield code="a">M</subfield>
           </datafield>
           <datafield tag="677" ind1=" " ind2=" ">
          <subfield code="a">Wird i.d.R. nur verwendet, wenn die Maltechnik behandelt ist.</subfield>
           </datafield>
           <datafield tag="750" ind1=" " ind2="7">
          <subfield code="a">Peinture à l'huile</subfield>
          <subfield code="0">(FrPBN)FRBNF119329441</subfield>
          <subfield code="0">http://data.bnf.fr/11932944</subfield>
          <subfield code="2">ram</subfield>
          <subfield code="9">v:MACS-Mapping. Bitte keine Änderungen vornehmen.</subfield>
           </datafield>
           <datafield tag="913" ind1=" " ind2=" ">
          <subfield code="S">swd</subfield>
          <subfield code="i">s</subfield>
          <subfield code="a">Ölmalerei</subfield>
          <subfield code="0">(DE-588c)4043238-5</subfield>
           </datafield>
        </record>
     </recordData>
     <recordPosition>1</recordPosition>
      </record>
   </records>
   <nextRecordPosition>2</nextRecordPosition>
   <echoedSearchRetrieveRequest>
      <version>1.1</version>
      <query>WOE=4043238-5 and COD=s</query>
      <xQuery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
      <recordSchema>MARC21-xml</recordSchema>
   </echoedSearchRetrieveRequest>
   <extraResponseData>
      <accountOf xmlns="">Staatsbibliothek zu Berlin - Preußischer Kulturbesitz, bpk-Bildagentur</accountOf>
   </extraResponseData>
</searchRetrieveResponse>

When I run my php code below I only get a blank page. Which code is missing to access for example datafield with tag 150 and the corresponding subfield? What did I miss?

php code:

header('Content-type: text/html; charset=utf-8');
error_reporting(E_ALL);
$id = $_POST["id"];             

// URL to fetch
$url = "https://services.dnb.de/sru/authorities?version=1.1&operation=searchRetrieve&query=WOE%3D$id%20and%20COD%3Ds&recordSchema=MARC21-xml";

// Setting the HTTP Request Headers
$User_Agent = 'Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0';

$request_headers = array('Contect-Type:text/xml', 'Accept:text/xml');

$ch = curl_init($url);
// Set the url
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_USERAGENT, $User_Agent);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Execute
$result = curl_exec($ch); // Performs the Request, with specified curl_setopt() options (if any).

// Closing
curl_close($ch);
$xml = SimpleXMLElement($result) or die("Error: Cannot create object");
echo($xml);

I have looked around and found that it might be something to do with passing it to a string but then I get nothing on screen. Not even SimpleXMLElement Object.

Thanks for your help

miken32
  • 42,008
  • 16
  • 111
  • 154
SIB
  • 23
  • 1
  • 10
  • first up, XML is not Content-type: text/html; – delboy1978uk Sep 21 '18 at 15:14
  • secondly, a white screen of death is a 500 error. check the error_log, and get the exact error message. – delboy1978uk Sep 21 '18 at 15:14
  • Have you confirmed that `$result` is what you expect? – Patrick Q Sep 21 '18 at 15:15
  • Thirdly, simple XML is rubbish. DOMDocument is far superior. Check this guys question and my answer which gives a simple example of DOMDocument in action https://stackoverflow.com/questions/52427103/str-replace-issues-with-soap-envelope/52427598#52427598 – delboy1978uk Sep 21 '18 at 15:16
  • Patrick I'm guessing that the XML in his question is the XML he's trying to echo – delboy1978uk Sep 21 '18 at 15:16
  • 1
    @delboy1978uk I 100% agree. But that doesn't mean it's what is actually being received. – Patrick Q Sep 21 '18 at 15:17
  • @ Patrick Q. Yes $result is right. – SIB Sep 21 '18 at 15:18
  • @delboy1978uk i use "Content-type: text/html" as header because else i get a Parser Error like "No root element found" – SIB Sep 21 '18 at 15:20
  • Try using DOMDocument like my suggestion – delboy1978uk Sep 21 '18 at 15:22
  • 4
    `SimpleXMLElement` is a class name, not a function. Try instantiating it with `new` or use `simplexml_load_string` instead. – miken32 Sep 21 '18 at 15:23
  • You can't just `echo` a SimpleXMLElement. Well, you can, but you'll get the text content of the root node, which in this case is just a lot of white-space. If you want to access individual nodes, you'll need to use its access methods. – iainn Sep 21 '18 at 15:25
  • Possible duplicate of [How do you parse and process HTML/XML in PHP?](https://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php) – iainn Sep 21 '18 at 15:25
  • @miken32 i tried both. Non of them works. – SIB Sep 21 '18 at 15:25
  • BTW, error_reporting by itself might not make error actually be shown, make sure to also add `ini_set('display_errors', '1');`. – Félix Adriyel Gagnon-Grenier Sep 21 '18 at 15:54

2 Answers2

1

SimpleXMLElement is a class name, not a function. Try instantiating it with new:

$xml = new SimpleXMLElement($result);

Or use simplexml_load_string instead.

$xml = simplexml_load_string($result);

Additionally, you're vastly over-complicating things with all the curl code. This should work just as well:

// ALWAYS sanitize user-submitted data
// in this example everything except numbers and hyphens are removed
$id = preg_replace("/[^0-9-]/", "", $_POST["id"]);
$url = "https://services.dnb.de/sru/authorities?version=1.1&operation=searchRetrieve&query=WOE%3D$id%20and%20COD%3Ds&recordSchema=MARC21-xml";
$xml = new SimpleXMLElement($url, 0, true);
miken32
  • 42,008
  • 16
  • 111
  • 154
  • I tried both. Non of them works. When I remove "curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);", the data of the XML file is displayed. However, the whole file and not the desired values. – SIB Sep 21 '18 at 15:30
  • You don't need the curl at all. The `SimpleXMLElement` constructor fetches the data for you. – miken32 Sep 21 '18 at 15:31
  • @SIB You haven't written any code to access your "desired values" - how are you expecting it to do anything else? – iainn Sep 21 '18 at 15:31
  • @iainn i tried for hours but i didnt get it right. Thats why i ask here and hope for examples or solutions. – SIB Sep 21 '18 at 15:33
0

The comments and other answer cover the reason why you're not getting any output. It's because of the missing new keyword. This will show you how to take the resulting object and parse it to get the desired subfield. This simply dumps the subfield object, but you can do whatever you want with it from here.

$xmlObj = new SimpleXMLElement($xml);

foreach($xmlObj->records->record->recordData->record->datafield as $dfield)
{
    if((string)$dfield["tag"] == "150")
    {
        $subfield = $dfield->subfield;
        var_dump($subfield);
    }
}

DEMO

Patrick Q
  • 6,373
  • 2
  • 25
  • 34