By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,664 Members | 1,656 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,664 IT Pros & Developers. It's quick & easy.

PHP saving embedded HTML in XML

P: n/a
I hope there is a simple solution to this, but I've been unable to
find it.
$dom = new DomDocument();
$dom->load("test.xml");

$test = $dom->getElementsByTagName("test");
$test->nodeValue = "<b>test</b>";
$dom->save("test.xml");
I would like the node in the xml file to look like:
<test><b>test</b></test>

Rather than the encoded version.
&lt;b&gt;test&lt;/b&gt;

What can be done to accomplish this task?

Thank you
dwain

Feb 21 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
dc******@gmail.com wrote:
I hope there is a simple solution to this, but I've been unable to
find it.
$dom = new DomDocument();
$dom->load("test.xml");

$test = $dom->getElementsByTagName("test");
$test->nodeValue = "<b>test</b>";
$dom->save("test.xml");
I would like the node in the xml file to look like:
<test><b>test</b></test>

Rather than the encoded version.
&lt;b&gt;test&lt;/b&gt;

What can be done to accomplish this task?

Thank you
dwain
From what I can see, it's not really possible - if it was possible, and
you tried to re-read the resulting xml file back, you would end up with
something like:

....
<test>
<b>
test
</b>
</test>
....

where <bis a child node of the <testnode, rather than part of the
value of the <testnode.

Therefore, entities like < and do need to be encoded / decoded
(possible with html_entity_decode()) when dealing with xml.

If, however, you *are* looking to add <bas a child node of <test>, I'm
sure there are functions to handle that ( probably something like $child
= $test->append_child('b') )
Feb 21 '07 #2

P: n/a
On Feb 21, 12:37 pm, Ian Taylor <m...@ocset.reverse.previous.word.net>
wrote:
dcrac...@gmail.com wrote:
I hope there is a simple solution to this, but I've been unable to
find it.
$dom = new DomDocument();
$dom->load("test.xml");
$test = $dom->getElementsByTagName("test");
$test->nodeValue = "<b>test</b>";
$dom->save("test.xml");
I would like the node in the xml file to look like:
<test><b>test</b></test>
Rather than the encoded version.
&lt;b&gt;test&lt;/b&gt;
What can be done to accomplish this task?
Thank you
dwain

From what I can see, it's not really possible - if it was possible, and
you tried to re-read the resulting xml file back, you would end up with
something like:

...
<test>
<b>
test
</b>
</test>
...

where <bis a child node of the <testnode, rather than part of the
value of the <testnode.

Therefore, entities like < and do need to be encoded / decoded
(possible with html_entity_decode()) when dealing with xml.

If, however, you *are* looking to add <bas a child node of <test>, I'm
sure there are functions to handle that ( probably something like $child
= $test->append_child('b') )- Hide quoted text -

- Show quoted text -

Thank you for the advice,

I'm looking to save HTML inside the XML, for that example that text
may be viewed bold when shown in a browser.

------------------------------------ Test.xml
<?xml version="1.0"?>
<ROOT>
<TEST>
<NAME>TEST PRODUCT 01</NAME>
<DESC>This is a test product, this is <b>bold</b>.</DESC>
<PRICE>9.99</PRICE>
</TEST>
</ROOT>

------------------------------------ Test.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:output method="html"/>

<xsl:template match="/">
<html>
<xsl:for-each select="ROOT/TEST">
<P>
<hr />
<xsl:value-of select="NAME" /<br />
<xsl:copy-of select="DESC |text()"/ <br />
<xsl:value-of select="PRICE" /<br />
<hr />

</P>
</xsl:for-each>

</html>
</xsl:template>
</xsl:stylesheet>

------------------------------------------------------- Test.php
<?php

$xsl = new DomDocument();
$xsl->load("test.xsl");

$inputdom = new DomDocument();
$inputdom->load("test.xml");

$proc = new XsltProcessor();
$xsl = $proc->importStylesheet($xsl);

$newdom = $proc->transformToDoc($inputdom);
print $newdom->saveXML();
?>

----------------------------- Result
<?xml version="1.0" standalone="yes"?>
<html><P><hr/>TEST PRODUCT 01<br/>

<DESC>This is a test product, this is <b>bold</b>.</DESC>

<br/>9.99<br/><hr/></P></html>

-------------------------------- The problem

When a XML document is saved by PHP it looks like

<?xml version="1.0"?>
<ROOT>
<TEST>
<NAME>TEST PRODUCT 01</NAME>
<DESC>This is a test product, this is &lt;b&gt;bold&lt;/b&gt;.</
DESC>
<PRICE>9.99</PRICE>
</TEST>
</ROOT>

I need to be able to save the XML Doc after altering it in PHP:
EX:
$node->nodeValue = "This is a test product, this is <b>bold</b>.";
$dom->save("test.xml");

without encoding the "<b>"'s.

Feb 21 '07 #3

P: n/a
I have 2 different fixes, one is to a PHP function to swap the chaters
as needed:

function fixXML($string){

for($i=1; $i < strlen($string);$i++) {
$subs1 = substr ($string, $i, 4);

switch ($subs1) {
case "&gt;":
$string = substr ($string, 0, $i) . ">" . substr ($string, $i +4,
strlen($string));
break;
case "&lt;":
$string = substr ($string, 0, $i) . "<" . substr ($string, $i +4,
strlen($string));
break;
}
}// end for
return $string;
}

<... code ..>

print fixXML($dom->saveXML());
and another way it can be done in the XSL. I thought this method was
allot messer.... and you would need to call for each charater you need
to swap out.

Snips from test.xsl
--------

<xsl:variable name="myString" select="HEADLINE" />
<xsl:variable name="myNewString">
<xsl:call-template name="SubstringReplace">
<xsl:with-param name="stringIn" select="$myString" />
<xsl:with-param name="substringIn" select="'&lt;'"/>
<xsl:with-param name="substringOut" select="'%3C'"/>

</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat(' input: ',$myString,' output: ',
$myNewString)" />
<xsl:template name="SubstringReplace">
<xsl:param name="stringIn" />
<xsl:param name="substringIn" />
<xsl:param name="substringOut" />
<xsl:choose>
<xsl:when test="contains($stringIn,$substringIn)">
<xsl:value-of select="concat(substring-before($stringIn,
$substringIn),$substringOut)" />
<xsl:call-template name="SubstringReplace">
<xsl:with-param name="stringIn" select="substring-after($stringIn,
$substringIn)" />
<xsl:with-param name="substringIn" select="$substringIn" />
<xsl:with-param name="substringOut" select="$substringOut" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$stringIn" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

I hope this helps someone.

good luck

Feb 21 '07 #4

P: n/a
On Feb 21, 5:37 pm, Ian Taylor <m...@ocset.reverse.previous.word.net>
wrote:
dcrac...@gmail.com wrote:
I hope there is a simple solution to this, but I've been unable to
find it.
$dom = new DomDocument();
$dom->load("test.xml");
$test = $dom->getElementsByTagName("test");
$test->nodeValue = "<b>test</b>";
$dom->save("test.xml");
I would like the node in the xml file to look like:
<test><b>test</b></test>
Rather than the encoded version.
&lt;b&gt;test&lt;/b&gt;
What can be done to accomplish this task?
Thank you
dwain

From what I can see, it's not really possible - if it was possible, and
you tried to re-read the resulting xml file back, you would end up with
something like:

...
<test>
<b>
test
</b>
</test>
...

where <bis a child node of the <testnode, rather than part of the
value of the <testnode.

Therefore, entities like < and do need to be encoded / decoded
(possible with html_entity_decode()) when dealing with xml.

If, however, you *are* looking to add <bas a child node of <test>, I'm
sure there are functions to handle that ( probably something like $child
= $test->append_child('b') )
Hi

You can do it like Ian said:

$elem = $dom->createElement('b');
$elem->nodeValue = 'test';
$test->appendChild($elem);

Or using a document fragment

$fragment = $dom->createDocumentFragment();
$fragment->appendXml('<b>test</b>');
$test->appendChild($fragment);

Feb 22 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.