Hi,

I'm hoping someone can help me. I'm trying to parse an xml file that is contained within a Powerpoint presentation. I'm naming the .pptx to .zip and extracting the files to the server. This is all well and good, but when it comes to getting to the information I want to get to I have problems. This is a sample of the xml I'm parsing.

<p:sld>
   <p:cSld>
      <p:bg>
         <p:bgPr>
            <a:blipFill>
               <a:blip r:embed="rId2"/>
               <a:tile tx="0" ty="0" sx="100000" sy="100000" flip="none" algn="tl"/>
            </a:blipFill>
            <a:effectLst/>
         </p:bgPr>
      </p:bg>

I'm wanting to store the attribute "r:embed" within the tag a:blip as a variable. At the moment I'm using SimpleXML. I was able to get to attributes that don't have a namespace in a tag that does have a namespace by using xpath.

$xml = simplexml_load_file('ppt/presentation.xml');
$result = $xml->xpath('p:sldSz');
$width = $result[0]['cx'][0];

// This allowed me to pull the attribute 'cx' from <p:sldSz>

//<p:sldSz cx="9144000" cy="6858000" type="screen4x3"/>

But the r:embed can't be pulled out. The closest I got was using print_r to output the value

					
foreach ($xml3->xpath('//a:tile') as $c) {
 	print_r($c);
	$sx = $c[0]['sx'][0];
	echo "SX = $sx<br />";
}
foreach ($xml3->xpath('//a:blip') as $c) {
	$ns_dc = $c->children("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
	print_r($ns_dc);
	$sx = $ns_dc[0]['embed'][0];
	echo "SX = $sx<br />";
} 
//SimpleXMLElement Object ( [@attributes] => Array ( [tx] => 0 [ty] => 0 [sx] => 100000 [sy] => 100000 [flip] => none [algn] => tl ) ) SX = 100000
//SimpleXMLElement Object ( [@attributes] => Array ( [embed] => rId2 ) ) SX = 

It's almost like the variable $ns_dc stores the attribute as a key and a value, but it can't be accessed. I can get the values in a:tile but not a:blip.

Anybody able to help or suggest an alternate method that would be able to pull out the r:embed value?

Thanks in advance.

    Your snippet of XML is incomplete, so it's a little hard to test, but you might want to use SimpleXML's registerXPathNamespace method to register the namespaces used (the document should declare some namespace->URL mappings of the form xmlns:a=http://www.example.com/ and you'd be best off using those when you register them for XPath. You can get a list with the getDocNamespaces method).

      I used getDocNamespaces to register them...

      				
      $ns = $xml3->getDocNamespaces();
      foreach($ns as $k => $v){
          $xml3->registerXPathNamespace($k, $v);
          echo "$k======>$v<br />";
      }

      But it didn't seem to make any difference

        I found 'a' solution but it's not very clean...

        $this_slide = "ppt/slides/slide1.xml";
        $file=fopen($this_slide,"r"); //open up the xml file
        while(!feof($file))
         {
        	 $xml3.= fgets($file); //append each line to $xml3
        }
        fclose($file); // close file
        $xml3 = str_replace("a:blip","ablip",$xml3); //replace all instances of a:blip with ablip
        $xml3 = str_replace("r:embed","rembed",$xml3);//replace all instances of r:embed with rembed
        $xml3 = simplexml_load_string($xml3); //load in the xml as a string
        $result = $xml3->xpath('//ablip'); //find all instances of ablip
        foreach($result as $t7){ 
        	$embed = $t7['rembed'][0]; //and pull out the attribute rembed
        	echo "<br />EMBED = $embed<br />";
        }

        It works, just not very happy with the bodge it solution.

          To be honest I usually use the DOM interface.

          <?php
          $doc = new DOMDocument;
          $doc->load('g:\presentation.xml');
          $xpath = new DomXPath($doc);
          
          $ids = $xpath->query('//p:sldId/@r:id');
          foreach($ids as $id)
          {
          	echo $id->value,"\n";
          }

          (The query is different because there are no blips or embeds in your posted file).

            Weedpacket wrote:

            To be honest I usually use the DOM interface.

            <?php
            $doc = new DOMDocument;
            $doc->load('g:\presentation.xml');
            $xpath = new DomXPath($doc);
            
            $ids = $xpath->query('//p:sldId/@r:id');
            foreach($ids as $id)
            {
            	echo $id->value,"\n";
            }

            (The query is different because there are no blips or embeds in your posted file).

            Errr.... That does it... Thanks. Seems so simple now. 😕 😃

            Better than my bodge-it-n-scarper method.

            Oh, I did upload the wrong xml file... whoops.

            Thanks again.

              Write a Reply...