Jump to content

Dom Nodevalue Encoded Problem


bakunin

Recommended Posts

The code works with no error, but i have a problem, when i want to send data into a node wich has "<"or ">" in it, then it will replace them by <

$dom = new DOMDocument( );$dom->load("../xsl/afile.xsl");	$value = "<test>";$xp = new DomXPath($dom);$res = $xp->query('//xsl:template[@name="'.$name.'"]'); $res->item(0)->nodeValue = $value;$dom->load("../xsl/afile.xsl");

So: <test> ends up in: <test>I understand that it may not be allowed to have "<" in a nodeValue in XML but im working on a XSL node and they are loaded with "<" and ">" to get params, to do loops, show variable and etc...What can i do to prevent it from encoding when they save it in a nodeValue.

Link to comment
Share on other sites

Tried escaping them with a backslash?

Link to comment
Share on other sites

PHP handles different parentheses differently...it may prefer ' '. I believe that ' ' is taken more literally than "", and your characters may not be encoded between them.

Link to comment
Share on other sites

This is to be expected. The idea of DOM is to make it so that it's (next to?) impossible for you to disturb its well formed structure, while still letting you manipulate it.If you want to create an element, use the appendChild() method on the node in which you want to insert the element. As an argument, give it a DOMElement instance. For example:

$res->item(0)->appendChild($dom->createElement('test', 'test value'));

If you really want to put in "raw" XML text, there are two possible ways. I'm going to tell you about the standard one. The non standard one is a little bit more convinient, but it leads to some bad habbits (and besides, you can find it yourself from PHP's DOM documentation), so...Create another DOMDocument object with the raw XML as content, and load the actual content with loadXML(). Then import the root element of this document to the initial document, and append the copied node. Like so:

$tmpDom = new DOMDocument;if (!$tmpDom->loadXML($value)) {//$value is not a well formed action. Take error handling actions here}$res->item(0)->appendChild($dom->importNode($tmpDom->documentElement, true));

Link to comment
Share on other sites

boen_robot, i wish i knew as much stuff as you ! :)I tryed it, works great except that it mess up my xsl tag:

<xsl:attribute name="id">item_<xsl:value-of select="@id"></xsl:value-of>_select</xsl:attribute>

becomes:

<attribute name="id">item_<value-of select="@id"></value-of>_select</attribute>

What is the non-standard way ?

Link to comment
Share on other sites

boen_robot, i wish i knew as much stuff as you ! :)
I'll let you in on a secret - I'm really a noob. I don't really know much about PHP other than its syntax and it's place in a web page's workflow. I can rarely do anything in PHP without reading the manual. The same goes for pretty much anything I use - I can rarely do anything beyond the basics without reading a reference, a specification or relying on an editor to suggest something appropriate... and this is actually why I may appear to know things - I know that something should be doable with something, I search for it in the manual, and in most cases, I find it.It is for this very reason that I will (again) not tell you about the non standard method. I would really prefer it if you find it yourself. Take it as an excersise for future's sake. I already gave you a hint where to look for it. I'll give you another hint - look at the DOM specifcation or the DOM reference at W3Schools. The PHP manual contains three funcions/classes that aren't in other references. One is the whole DOMXPath class (well... W3C has DOM 3 XPath, but PHP's implmentations is far from it), the other is the function for SimpleXML migration. That third non standard feature is the one you're looking for.
I tryed it, works great except that it mess up my xsl tag:
<xsl:attribute name="id">item_<xsl:value-of select="@id"></xsl:value-of>_select</xsl:attribute>

becomes:

<attribute name="id">item_<value-of select="@id"></value-of>_select</attribute>

What is the non-standard way ?

You need to declare the xsl namespace somewhere in $tmpDom, perhaps with a "dummy root" element that will declare it, and then put up $value within it. That is, like:
loadXML('<root xmlns:xsl="...">' . $value . '</root>');

(as you can see, I don't know the "xsl" namespace URI by heart either...)

Link to comment
Share on other sites

I found:

$tmpDom->recover=true;

So now i can add not well formed xml.I can use:

if (!$tmpDom->loadHTML($value))

wich is perfect because it does not need to be well formed but then i get "<html><body>" tag. So i have to copy the value of the body tag only.

Link to comment
Share on other sites

i found it ! :) DOMDocumentFragmentStill not working 100% but getting close. I hate it because i lose 1 day to try to do something very simple... but there is always something going wrong lol !Its hard because appendXML won't work if the xml is not valid, but at least it does not encode my stuff. It always either encode my stuff or refuse to append it.so lets say i try to add:

<input type="submit">

in it then it will give an error.then i addthis and it work

<input type="submit"/>

but it append this->

<input type="submit">

so they append stuff that are not valid.I guess im cheating a bit, i don't want it to be well formed because technically its not an xml file, its an xsl file even if xsl is supposed to be xml... i guess xsl is not well formed... im putting xsl stuff in it... and html stuff and it does not like it, but its going to have to deal with it because i won't stop looking till it work 100% :).But im starting to wonder if it is just not impossible using dom... i know i can do a not well formed by hand and make dom read it... but i can't use dom to add not well formed stuff... it will always try to make it well-formed or it will refuse to add it...

Link to comment
Share on other sites

XSLT is an XML based language, so just like any other XML language - if you end up with a non well formed file, your file will be useless from then on.DOMDocumentFragment is indeed the class I was hinting about - see how easy it was :) ?Even DOMDocumentFragment requires that your fragment is well formed. The only limitation that is lifted with it is the requirement for a root element (hence, a fragment).Since this is XSLT, you can add

<input type="submit"/>

and then, if you have (at the top level)

<xsl:output method="html"/>

this element will be serialized as

<input type="submit">

in the final output.

Link to comment
Share on other sites

I finally did use file_put_contents() to force it and send my data to the server... and you know what ? when i do that, if it detect that it is not well formed, the whole xml file get automatically regenerated to be well formed ! :) in other word when you say its "next to impossible", you were right ! Im back to square one ! so this time i decided to explore the CDATA way... my code get put in the file fine, it is well formed... but its encoded when it transform an xml file :) ...Then i decode it... and the xsl in the CDATA does not execute... for sample:

<div>			<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute> </div>

the <xsl:attribute> is not applied.

Link to comment
Share on other sites

file_put_contents() is not part of DOM, so technically speaking, you still haven't done the "next to" part I was reffering to :) .CDATA is just a syntax sugar for text nodes.

<element><![CDATA[a<>b&&c<d]]></element>

is equivalent of

<element>a<>b&&c<d</element>

That is, DOM and other XML parsers read them in the same way. I suggest you shy away from CDATA, and just use DOM's nodeValue. As you already saw, it automaically encodes special characters, so that the usefulness of CDATA is no more.BTW, CDATA also has one limitation - it must not contain the string "]]>". If it does, the CDATA node will be cut of there, and the rest will be seen as a separate text node, with all of its limitations.I'm also not sure that the file "automatically regenerated to be well formed" (there's no such notion... you've worked around it with "manual" matters without realizing it)... did you used loadHTMLFile() instead of loadXML()? If so, that would explain it. loadHTMLFile() is fault tolerant, but removes namespace declarations. If you used it only over the fragment, then then imported it to the original document, you could've worked around this. Whether you use file_put_contents($filename, $dom->saveXML()) or $dom->save($filename) is irrelevant to the well formdness, and the latter is actually faster.

Link to comment
Share on other sites

I think im gonna start from scratch, im gonna save my script, html and php in a separate file outside of my xsl file. this way i can keep the well formed stuff and non well formed stuff separatly.Then im gonna import it or use a template engine to fill the data in the right place.

Link to comment
Share on other sites

I think im gonna start from scratch, im gonna save my script, html and php in a separate file outside of my xsl file. this way i can keep the well formed stuff and non well formed stuff separatly.Then im gonna import it or use a template engine to fill the data in the right place.
I must say... I don't get it.XSLT is used to turn one XML data (your dialect) into another XML data (XHTML). XML files must be well formed, which is, in its core, a good thing.You may create whatever editor you want, but in the end of the day (session), it must still submit a text that would have to represent the whole template (i.e. XSLT code with XHTML in it) or portions of it (i.e. XSLT or XHTML code). Even if you were to define and implment your own transformation language, the submitted text must still be a well formed XML or XML fragment.Why not simply disallow non well formed stuff, and show the user an error message? Doing so is trivial - just check whether loadXML() returns true. If it doesn't, it means the XML is not well formed.If you let the user just fill it the data, that's another thing - do use a templating engine for that, or implement it on top of your own. But if you want to let the user edit the whole template (XHTML and stuff...), what you had started doing was the right thing.
Link to comment
Share on other sites

Im not sure, if Well formed meant clean and well written HTML, i would agree. Usually when i code in html i would do ("<input>" wich is not allowed) But i agree, no big deal, i write well formed stuff ("<input/>") and it works. So i do append or whatever to save it to the node, they strip my "/" so what is saved is in theory non-well formed HTML ("<input/>" become "<input>") so the second time when i extract my data from the node to put it in a textbox(i get "<input>"), it means even if i don't change what i extracted from the node, i can't save it back, i click save and it gives me an error :).The other reason is i want the user to be able to save PHP and Javascript also wich can't be contained in node (not well-formed stuff).

Link to comment
Share on other sites

The other reason is i want the user to be able to save PHP and Javascript also wich can't be contained in node (not well-formed stuff).
Why? PHP should be kept separate, and used only for "controlling" stuff, not for templating. And JavaScript should be kept separate too, whenever possible, and kept in a "controlling" fashion, similarly to PHP, but on the client. Your XHTML should only contain "hooks" for JavaScript. And if you need to execute PHP... you probably need to group that functionality in a separate XSLT template, that you edit with another instance of this same editor.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...