Author
|
Message
|
Pascal Specht
|
Monday 10 September 2007 7:47:32 am
Hi, can someone help me understand what I'm doing wrong? I'm using a text attribute (data_text_1) in an order. This text attribute contains a serialized dom tree like:
<?xml version="1.0" encoding="UTF-8"?>
<shop_account>
<salutation>1</salutation>
<first-name>Pascal</first-name>
<last-name>Specht</last-name>
...
<transaction>[no transaction]</transaction> </shop_account> and I'd like to change the content "[no transaction]" to "[test]"... I thought that I could do that by unserializing, then grabbing the element with elementsByName, and applying setAttribute and writing back as a string, but it doesn't... The node still contains [no transaction]!
$xml = new eZXML();
$xmlDoc =& $order->attribute( 'data_text_1' );
if( $xmlDoc != null )
{
$dom =& $xml->domTree( $xmlDoc );
if ($dom)
{
$item =& $dom->elementsByName( "transaction" );
$item->setAttribute( 'data_text', "[test]" );
}
}
$order->setAttribute( 'data_text_1', $xmlDoc->toString() );
Obviously this doesn't work. Any ideas how to correct the problem would be greatly appreciated! Pascal
|
Pascal von Büren
|
Monday 10 September 2007 8:55:42 am
Hi Pascal, your code ends quite quickly, did you call
$order->store();
afterwards?
|
Pascal Specht
|
Tuesday 11 September 2007 2:27:29 am
Hi Pascal, I must admit I hadn't the order->store() instruction, but unfortunately, after adding it (and clearing the cache) it doesn't get better, the order still is unchanged. I suppose the two $item-> instructions to be wrong...
Thanks for your help, Pascal
|
Pascal von Büren
|
Tuesday 11 September 2007 3:15:19 am
Ok, i can see two more possilbe problems. First of all, <b>elementsByName</b> returns an Array. So you could look over the result or use <b>elementByName</b>. Additionally, you want to set the TextContent of a Node, but you use setAttribute. You'd be off better using <b>setContent</b>. One more question: How are you calling this script? By CLI or as HTTP request?
|
André R.
|
Tuesday 11 September 2007 3:43:56 am
Something like this maybe?
$items =& $dom->elementsByName( "transaction" );
// Note: php4 foreach copy's array values instead of referencing them
for( $i = 0, $c = count( $items ); $c > $i ; $i++)
{
$items[$i]->setContent("[test]");
//$items[$i]->setAttribute( 'data_text', "[test]" ); this will result in <transaction data_text="[test]">[no transaction]</transaction>
}
eZ Online Editor 5: http://projects.ez.no/ezoe || eZJSCore (Ajax): http://projects.ez.no/ezjscore || eZ Publish EE http://ez.no/eZPublish/eZ-Publish-Enterprise-Subscription
@: http://twitter.com/andrerom
|
Pascal Specht
|
Tuesday 11 September 2007 5:39:15 am
I built in both of your suggestions, and I have now this code, which apparently does not raise any warnings or errors. The thing is that the setContent("[test]") now gets called but when I look at my data_text_1, it still contains the original XML + the two ## on each side...
$xml = new eZXML();
$xmlDoc =& $order->attribute( 'data_text_1' );
if( $xmlDoc != null )
{
$dom =& $xml->domTree( $xmlDoc );
if ($dom)
{
$items =& $dom->elementsByName( "transaction" );
for( $i = 0, $c = count( $items ); $c > $i ; $i++)
{
$items[$i]->setContent("[test]");
$items[$i]->store();
}
}
}
$str = "##" . $dom->toString() . "##";
$order->setAttribute( 'data_text_1', $str );
$order->store();
Originally, what I wanted to do is simply add one item into a string based XML text... Any help much appreciated!
|
Pascal von Büren
|
Tuesday 11 September 2007 7:24:54 am
Hi Pascal, one more try:
$xml = new eZXML();
$xmlDoc =& $order->attribute( 'data_text_1' );
if( $xmlDoc != null )
{
$dom =& $xml->domTree( $xmlDoc );
if ($dom)
{
$root =& $dom->root();
$items =& $root->elementsByName( "transaction" );
for( $i = 0, $c = count( $items ); $c > $i ; $i++)
{
$items[$i]->setContent("[test]");
}
}
}
$str = "##" . $dom->toString() . "##";
$order->setAttribute( 'data_text_1', $str );
$order->store();
(getting the elements starting from DOM-Root)
|
Pascal Specht
|
Tuesday 11 September 2007 8:24:59 am
Hi,
This really drives me crazy! I spent the whole day on it, and it still doesn't work... Obviously the code changes the node content, but the final result doesn't reflect the change!
$xml = new eZXML();
$xmlDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <a> <xxx>*</xxx> </a>";
if( $xmlDoc != null )
{
$dom =& $xml->domTree( $xmlDoc );
if ($dom)
{
$root =& $dom->root();
$items =& $root->elementsByName( "xxx" );
for( $i = 0, $c = count( $items ); $c > $i ; $i++)
{
$items[$i]->setContent("**********");
echo "!item change occured!";
}
}
}
echo "<hr><pre>";
echo htmlspecialchars( $xmlDoc );
echo "<hr>";
echo htmlspecialchars( $dom->toString() );
echo "<hr></pre>";
produces the following output:
!item change occured!
--------------------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<a>
<xxx>*</xxx>
</a>
--------------------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<a>
<xxx>*</xxx>
</a>
--------------------------------------------------------------------------------------------------------------------------------
|
Pascal Specht
|
Tuesday 11 September 2007 9:18:33 am
OK, so for anyone interrested in doing it, I found the solution now: To replace all occurences of <xxx>*</xxx> you can do:
$xml = new eZXML();
$xmlDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <a> <xxx>*</xxx> </a>";
if( $xmlDoc != null )
{
$dom =& $xml->domTree( $xmlDoc );
if ($dom)
{
$root =& $dom->root();
$items =& $root->elementsByName( "xxx" );
for( $i = 0, $c = count( $items ); $c > $i ; $i++)
{
$element = $items[$i];
if ( count( $element->Children ) > 0 )
{
foreach( array_keys( $element->Children ) as $key )
{
$child =& $element->Children[$key];
$child->setContent("**********");
}
}
}
}
}
|