xsl-list
[Top] [All Lists]

Re: Subject: RE: [xsl] XML fragment as a param ?

2005-11-15 11:37:57
When I do this :-

transformer.setParameter(param.name, param.value);

where param.name and param.value are both Strings and contain -
"inboundXML"
and "<Numbers><Odds><One>1</One>... "

and when the stylesheet looks like this :-

...
  <xsl:param name="inboundXML" select="/"/>
  <xsl:template match="/">
    <rootContainer>
        <xsl:copy-of select="$inboundXML"/>
    </rootContainer>
  </xsl:template>
...

I get this (almost correct but no cigar :-) :-

<rootContainer>
        &lt;Numbers&gt;&lt:Odds&gt;&lt;One&gt;1.....
</rootContainer>


That's because you passed in a string containing characters which have to
be escaped in XML ("<" and ">" for example), so they were escaped to
ensure that the output was well-formed. You could use
"disable-output-escaping" if passing in a string is the path you want to
pursue.


Previously Michael commented :-


Michael> Most products will allow you to supply a DOM
node (they
Michael> may restrict which DOM implementations you are allowed to use).
Saxon allows
Michael> you to supply any JAXP Source object, so if you supply a
StreamSource
Michael> containing raw XML, the XML will be parsed and the stylesheet
will
see the
Michael> resulting document node as the parameter value.

That's interesting I thought so I tried doing this (admittedly I'm not
using
Saxon (sorry Michael) so no guarantees) :-

transformer.setParameter(param.name, new StreamSource(new
StringReader(param.value)));

but unfortunately all that gave me was :-

<rootContainer>javax(_dot_)xml(_dot_)transform(_dot_)stream(_dot_)StreamSource(_at_)4c6ca8b6</rootContainer>


Which is also correct (in your environment) as that is the string
representation of the StreamSource: clearly the processor you are using
doesn't support using a StreamSource as a parameter, and so took the
result of that object's toString() method.

Have you tried passing a DOM node, as Michael suggested before mentioning
the StreamSource? You could then use:

   <xsl:param name="inboundXML" select="/"/>
   <xsl:template match="/">
     <rootContainer>
         <xsl:apply-templates select="$inboundXML"/>
     </rootContainer>
   </xsl:template>

   <xsl:template match="Numbers">
      <!-- at this point you have matched the Numbers element in
           your inboundXML DOM, so do whatever you planned with it
      -->
   </xsl:template>

If the XML you want to pass in is already in DOM form, then just use
setParameter (the following is JavaScript/MSXML, but should give you the
idea):

var requiredNode =
additionalDocument.selectSingleNode("/document/containing/desired/Numbers");
xslProcessor.addParameter("inboundXML", requiredNode); // setParameter in
your case
xslProcessor.transform();

If you have the XML as a string, you'll probably want to scroll back up
and look into the disable-output-escaping option, although this can have
undesired side effects: in the future, somebody could pass any string into
your code and make it produce ill-formed output (for example, passing in
"<<<").

I have tried using the exslt:node-set function, but I'm not sure I got it
correct.


The extension "node-set" function will convert a result tree fragment into
a node set, so isn't really relevant in this case - although I may be
wrong, as every time I mention result tree fragments I make some basic
mistake, which Michael kindly corrects :-)

HTH,

Nick.
-- 
Nick Fitzsimons
http://www.nickfitz.co.uk/


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>