0

This is related to PHP Dom Document.

I have sample file like below

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <items>
        <item class="pen">
            <no>1</no>
            <name>A</name>
            <price>10</price>
        </item>
        <item class="book">
            <no>2</no>
            <name>B</name>
            <price>20</price>
        </item>
        <item class="pen">
            <no>2</no>
            <name>C</name>
            <price>30</price>
        </item>
    </items>
</document>

PHP code

$nodeCount = $oElement;
$limitCount = 1;
$nodeCount = $nodeCount->nextSibling;
while($nodeCount && !empty($nodeCount) && $nodeCount->nodeType == 1 && !preg_match("/pen/",$this->GetNodeClass($nodeCount)))
{
    $limitCount++;
    $nodeCount = $nodeCount->nextSibling;
}

Here, GetNodeClass() checks for an attribute class and this is the culprit point from where error occurs

function GetNodeClass($oElement)
{
    //Error comes from below line when try to execute getAttribute() method on TextNode
    $class = $oElement->getAttribute('class');
    return $class;
}

When I traverse these elements, sometimes I receive errors like below

Fatal error: Call to undefined method DOMText::getAttribute() in

Then I have tried to solve it using below condition to prevent that error.

$node->nodeType == 1

In some cases it works properly but in some cases always it shows an error like explained. I knew that it comes because of some white space between nodes. But is there any other way to ignore those white space at the time of XML file reading? Because I have so much code written already so if there is some pin point solution for that.

I use DomDocument object for all this.

Any help will be appreciated.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Smile
  • 2,770
  • 4
  • 35
  • 57
  • Can you post the code you are currently using that is producing the said errors ? – Prix Jun 07 '13 at 10:14
  • @Prix, Appreciate your quick response and editing of related Tags in Question. Please find an appended code in question. – Smile Jun 07 '13 at 10:20
  • @NullVoid Any chance you can change to `$nodeList=$items->getElementsByTagName("item");`? – Passerby Jun 07 '13 at 10:28
  • @NullVoid have you tried using `$xmldoc->preserveWhiteSpace = false;` – Prix Jun 07 '13 at 10:29
  • @Passerby, Actually I load an entire file and using DomDocument I fetches descendant elements and then traverse them using `nextSibling` or `previousSibling` based on hierarchy of elements. So I cannot use the suggestion you provide :( – Smile Jun 07 '13 at 10:30
  • @Prix, No I haven't tried that one. I knew about it but have not gave chance to it. Let me check. – Smile Jun 07 '13 at 10:31
  • @Prix, Still same error – Smile Jun 07 '13 at 10:34
  • @NullVoid If I remember correctly, you need to `->preserveWhiteSpace=false` **before** you `->load()`. – Passerby Jun 07 '13 at 10:36
  • @Passerby, I also did as you suggested. like `$Dom = new DOMDocument("1.0", "utf-8"); $Dom->preserveWhiteSpace = false;` Is it correct like you said above? I did same but still error remains. – Smile Jun 07 '13 at 10:46

1 Answers1

1

I have just made a very simple code trying to reproduce your error but I was unable to, below follows the code which works just fine for me without any errors.

<?php

$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->load('data.xml');

foreach ($dom->getElementsByTagName('item') as $item)
{
        if (!preg_match("/pen/",GetNodeClass($item)))
        #if ($item->getAttribute('class') == 'book')
        {
                        echo "no." . $item->childNodes->item(0)->nodeValue . "\n";
                        echo "Name: " . $item->childNodes->item(1)->nodeValue . "\n";
                        echo "Price: " . $item->childNodes->item(2)->nodeValue . "\n";
                        echo "----------------------------\n";
        }
}

function GetNodeClass($oElement)
{
    $class = $oElement->getAttribute('class');
    return $class;
}
Prix
  • 19,417
  • 15
  • 73
  • 132
  • I appreciate your solution but I have already an API to handle all XML related operations. So I cannot implement above solutions :( – Smile Jun 07 '13 at 10:53
  • @NullVoid you don't have to implement mine but you can use as reference to find out why yours inst working. By the looks the error is within some node failing rather than your structure. – Prix Jun 07 '13 at 10:55
  • @NullVoid or you can post a working version of your API that we can use to debug and find out what may be breaking it. – Prix Jun 07 '13 at 10:57
  • @NullVoid yeah I am sorry the above code is based on what you can/showed me, from what you showed me I have seen no issues so perhaps you're traversing something that is breaking it at some point which is why you get the error message and without seeing more I just cant debug what it would be. The problem may lie within your while function but with this little amount of code it will be hard to pin point. Have a look at this, maybe this will also help you out: http://stackoverflow.com/questions/6356115/traverse-the-dom-tree – Prix Jun 07 '13 at 11:04
  • +1 Yes. Sure. I am just taking reference from your code and working on it. :( I just shown some sample in my question from which we can get idea that where I am doing mistake. Oh... You're right. – Smile Jun 07 '13 at 11:09
  • Sure I will see the reference you specified and will come back if I found solution which can help to prevent error :) – Smile Jun 07 '13 at 11:13