Friday, 15 August 2014

dom - xslt parse XML string into variable and use Xpath -



dom - xslt parse XML string into variable and use Xpath -

my (simplified) input xml file contains following:

<?xml version="1.0" encoding="utf-8"?> <main> <data_record> <message>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</message> </data_record> </main>

the message element value character-escaped xml instance. represents next xml:

<pd> <cdhead version="13"/> </pd>

i apply xsl transformation on input xml , somehow parse message contents variable , utilize xpath expressions access details. tried adding javascript function below, object returned script apparently of wrong dom subclass (see result underneath). completeness, added function returns dom contents string.

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:my="http://example.com/my" exclude-result-prefixes="ms my"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <ms:script language="jscript" implements-prefix="my"> <![cdata[ function parsetodom (input) { var doc = new activexobject('msxml2.domdocument.6.0'); doc.loadxml (input); homecoming doc.documentelement; }; function parsetoxmlstring (input) { var doc = new activexobject('msxml2.domdocument.6.0'); doc.loadxml (input); homecoming doc.documentelement.xml; }; ]]> </ms:script> <xsl:template match="/"> <root> <xsl:apply-templates/> </root> </xsl:template> <xsl:template match="data_record"> <xsl:variable name="dom"><xsl:copy-of select="my:parsetodom (message)"/></xsl:variable> <xsl:variable name="xml"><xsl:copy-of select="my:parsetoxmlstring (message)"/></xsl:variable> <msg1><xsl:value-of select="$xml"/></msg1> <msg2><xsl:value-of select="$xml" disable-output-escaping="yes"/></msg2> <dom><xsl:copy-of select="$dom"/></dom> <version><xsl:value-of select="$dom/pd/cdhead/@version"/></version> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>

result:

<?xml version="1.0" encoding="utf-8"?> <root> <msg1>&lt;pd&gt; &lt;cdhead version="13"/&gt; &lt;/pd&gt;</msg1> <msg2><pd> <cdhead version="13"/> </pd></msg2> <dom/> <version></version> </root>

how can create jscript function homecoming result allows utilize of xpath? way, there xslt 1.0 function available allows parsing escaped xml string result allows utilize of xpath?

addition

i have been trying variations , got closer solution. first, altova xmlspy allows choosing xsl processor, , above resulted when using built-in one. of course of study need msxml 6.0 , when choosing one, errors occurred had parse input.text instead. succeeded in beingness able utilize xpath expressions in result after doing stuff in javascript. transpired while &#60; , parsed &lt; etcetera, not plenty arrive @ proper dom result. resorted unescaping input string first. nail snag: below works fine, not when utilize input.text instead of literal below.

see below xslt.

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:my="http://example.com/my" exclude-result-prefixes="ms my"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <ms:script language="jscript" implements-prefix="my"> <![cdata[ function parsetodom (input) { var doc = new activexobject('msxml2.domdocument.6.0'); doc.loadxml (unescapexml ('&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;')); //doc.loadxml (unescapexml (input.text)); homecoming doc; }; function unescapexml (str) { var ostr = str; ostr = ostr.replace (/&#34;/g, '"'); ostr = ostr.replace (/&#60;/g, '<'); ostr = ostr.replace (/&#61;/g, '='); ostr = ostr.replace (/&#62;/g, '>'); homecoming ostr; }; ]]> </ms:script> <xsl:template match="/"> <root> <xsl:apply-templates/> </root> </xsl:template> <xsl:template match="data_record"> <xsl:variable name="msg" select="my:parsetodom (message)"/> <tst><xsl:value-of select="$msg/pd/cdhead/@version"/></tst> </xsl:template> </xsl:stylesheet>

now results in

<?xml version="1.0" encoding="utf-8"?> <root> <tst>13</tst> </root>

which want.

but remarked above, when comment parsing of literal , utilize input instead, so:

//doc.loadxml (unescapexml ('&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;')); doc.loadxml (unescapexml (input.text));

i next error (in altova xml spy msxml 6.0 xslt parser):

xsl transformation failed due next error: microsoft jscript runtime error 'undefined' null or not object line = 10, col = 3 (line offset start of script block). error returned property or method call.

which points @ first javascript replace statement.

and also, ie9 cannot process next properly:

<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="test.xslt"?> <main> <data_record> <message>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</message> </data_record> </main>

when open file in ie9 (where test.xslt version of transformation input ignored , instead literal processed, hence 1 ok in xml spy), processing error:

xml5001: applying integrated xslt handling. xslt8690: xslt processing failed.

why , how can right it?

starting addition above, reached solution finetuning little. avoid having input.text , utilize plain input instead, xsl has contain conversion of element string applying xslt string function (i thought string already, apparently not case). in addition, not necessary more apply replace statements now. thus

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:my="http://example.com/my" exclude-result-prefixes="ms my"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <ms:script language="jscript" implements-prefix="my"> <![cdata[ function parsetodom (input) { var doc = new activexobject('msxml2.domdocument.6.0'); doc.loadxml (input); homecoming doc; }; ]]> </ms:script> <xsl:template match="/"> <root> <xsl:apply-templates/> </root> </xsl:template> <xsl:template match="data_record"> <xsl:variable name="msg" select="my:parsetodom (string(message))"/> <tst><xsl:value-of select="$msg/pd/cdhead/@version"/></tst> </xsl:template> </xsl:stylesheet>

works: when applied on

<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="test.xslt"?> <main> <data_record> <message>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</message> </data_record> </main>

the result is

<?xml version="1.0" encoding="utf-8"?> <root> <tst>13</tst> </root>

unluckily, ie9 still fails in loading xml referred xslt; , discovered why. had tick box in net options/advanced/security/allow active content run in files on computer - , restart ie - makes ie9 process file correctly. of course, result not beingness html means result can viewed in f12/script tab, illustration , incorporate in xslt generates proper html.

xslt dom internet-explorer-9 xslt-1.0 jscript

No comments:

Post a Comment