DOMDocument trouble

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

DOMDocument trouble

Post by Paranoid »

Hello,
I've been trying to get this working for some time now but having no luck. Here's the code that I'm having trouble with, read on to understand my problem:

Code: Select all

 
$doc = new DOMDocument();
$doc->load($gigToSearch."GigInfo.xml"); // This is the problem.. It doesn't like it unless it's a file already there.
$venues = $doc->getElementsByTagName("event");
$fp2 = fopen($gigToSearch."Venue.xml", "w");
foreach ($venues as $venue) {
        $venuesID = $venue->getElementsByTagName("id");
        $venueID = $venuesID->item(0)->nodeValue;
        fwrite($fp2, '<id>');
        fwrite($fp2, $venueID);
        fwrite($fp2, '</id>');
  }
fclose($fp2);
 
Note: $gigToSearch is defined already in a previous part of my code, it's a name of a band or artist, e.g. Muse.

If I use:

Code: Select all

$doc->load("MuseGigInfo.xml");
It works fine.

But the problem is, I can't specify an exact XML file as depending on user input an XML file is downloaded and saved locally on the server with the appropriate name, which can then only be accessed using $gigToSearch."GigInfo.xml" like I do in my code to be able to fetch some data I need.

Using the original code I provided above it gives me the following error:

Warning: DOMDocument::load()[domdocument.load]: Document is empty file:///..../MuseGigInfo.xml

If I replace $gigToSearch."GigInfo.xml" with "MuseGigInfo.xml" and just try run an example for Muse it works fine.

I make sure I first download and write the file (and close it of course), but it still doesn't work.

Anyone have any ideas? The only thing I can think about is that $doc->load(); doesn't like anything but a statement enclosed inside quotes.

Thanks in advance!
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

Check the value of $gigToSearch using var_dump(). According to the error message, the string starts with "file://". That's atypical.

Check whether the file you are trying to open exists using file_exists() before you try to open it.

It is improper to use fopen()-style file editing with DOMDocument. Use DOM methods instead.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 1:56 pm, edited 1 time in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

McInfo wrote:Check the value of $gigToSearch using var_dump(). According to the error message, the string starts with "file://". That's atypical.

Check whether the file you are trying to open exists using file_exists() before you try to open it.

It is improper to use fopen()-style file editing with DOMDocument. Use DOM methods instead.
Thanks for your quick reply. Here's my results:

1) var_dump() returns string 'Muse' (length=4) which should be fine.

2) file_exists() shows me that the file I want to use exists.

So I can't see how it can be going wrong.

Could you clarify a bit more on what you mean that fopen()-style editing with DOMDocument is improper? What could I use instead?
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

After some sleep, I can see more clearly. The error message is telling you that the "document is empty" which means that there is nothing in the file. An XML file should contain at least one tag (the root tag) and preferably a document type (<?xml version="1.0" encoding="UTF-8"?>).

If you want to create a document instead of loading one from a file, you can start with DOMDocument::loadXML(). For example:

Code: Select all

$doc->loadXML('<root></root>');
Paranoid wrote:Could you clarify a bit more on what you mean that fopen()-style editing with DOMDocument is improper? What could I use instead?
The DOM classes handle manipulation of the XML structure so you are not writing the XML directly. Using fopen() and fwrite() to edit the XML bypasses any benefits you get from the DOM classes.

It looks like you are trying to copy elements from one XML file to another. To do this the DOM way, create two DOMDocument objects and import nodes from one document into the other.

a.xml - input

Code: Select all

<?xml version="1.0"?>
<a>
    <x>1</x>
    <x>2</x>
    <x>3</x>
</a>
example.php

Code: Select all

<?php
// Source document; loaded from a file
$d1 = new DOMDocument();
$d1->load('a.xml');
 
// Destination document; loaded from a string
$d2 = new DOMDocument();
$d2->loadXML('<b></b>');
 
// Finds all <x> tags in $d1
foreach ($d1->getElementsByTagName('x') as $x) {
    // Imports current <x> tag into $d2 and appends it to the root element (<b>)
    $d2->childNodes->item(0)->appendChild($d2->importNode($x, true));
}
 
// Saves $d2 to a file
$d2->save('b.xml');
b.xml - output

Code: Select all

<?xml version="1.0"?>
<b><x>1</x><x>2</x><x>3</x></b>
 
Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 1:58 pm, edited 1 time in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

You got the point of what I want to do, and your sample code looks great; I tried applying the same with your code for mine but it doesn't seem to work, it still gives me exactly the same error...

Here's the altered code:

The problem must be somewhere else I think.

Code: Select all

        $doc = new DOMDocument();
        $doc->load($gigToSearch.'GigInfo.xml'); // This is the problem.. It doesn't like it unless it's a file already there.
        $venues = $doc->getElementsByTagName("event");
        $doc2 = new DOMDocument();
        $doc2->loadXML('<event></event>');
        foreach ($venues as $venue) {
            $venuesID = $venue->getElementsByTagName("id");
            $venueID = $venuesID->item(0)->nodeValue;
            $doc2->childNodes->item(0)->appendChild($doc2->importNode($venueID, true));
        }
        $doc2->save($gigToSearch.'Venue.xml');
 
Edit: As long as I change $gigToSearch.'GigInfo.xml' into something like 'MuseGigInfo.xml' it works fine. But I can't do that, I need the input from $gigToSearch. And I'm using that value before to create another XML file like this which works fine. The XML file is created with no problems, so the problem mustn't be $gigToSearch.

Code: Select all

$ch1 = curl_init("*someAPIcall*=".$gigToSearch);
        $fp1 = fopen($gigToSearch."GigInfo.xml", "w");
        
        
        curl_setopt($ch1, CURLOPT_FILE, $fp1);
        curl_setopt($ch1, CURLOPT_HEADER, 0);
        
        
        curl_exec($ch1);
        curl_close($ch1);
        fclose($fp1);
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

1. It might be a character encoding issue. What looks like "Muse" might not actually be "Muse".

2. Check your XML file and confirm that it contains valid XML.

3. If you compress your files (.zip or .tar.gz) and upload them, I can try to figure out what is wrong.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 1:59 pm, edited 1 time in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

Yep my XML file contains valid data, as such:

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<response status="success" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos">
<events>
.... individual events here
</events>
</response>
Hmm, this is annoying...

I just don't get why it works fine for my other code but not for this one.
Last edited by Paranoid on Tue Nov 10, 2009 5:30 pm, edited 1 time in total.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

If you missed my update, read my last post.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 1:59 pm, edited 1 time in total.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

The <response> tag in your XML has no closing tag.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 2:00 pm, edited 3 times in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

I just missed pasting it but it's there! Will edit for clarity
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

What is your...
  • PHP version
  • HTTP server name and version
  • operating system name and version
Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 2:01 pm, edited 1 time in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

McInfo wrote:What is your...
  • PHP version
  • HTTP server name and version
  • operating system name and version
PHP Version: 5.2.10
OS Name & Version: MS Windows XP (Service Pack 3)
HTTP server name & version: Well currently I am working and testing on Aptana (http://aptana.org) which uses Jetty 6.1.11
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: DOMDocument trouble

Post by McInfo »

Focus on your cURL operation. "Document is empty" seems to indicate that cURL does not replace the XML in the file after fopen() truncates it. (Firewall?)

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Thu Jun 17, 2010 2:02 pm, edited 1 time in total.
Paranoid
Forum Newbie
Posts: 12
Joined: Mon Nov 09, 2009 7:54 pm

Re: DOMDocument trouble

Post by Paranoid »

Although I managed to get what I wanted in a different way, I just figured out the problem; all I needed was to just use trim() on the $gigToSearch variable.

Just so if anyone else is having similar problems with me, just use trim!
Post Reply