views:

271

answers:

2

Hi, I'm working on a XSLT transformation that consists on merging two XML and then transform the result using another template. The idea is that depending on a field of the original XML file, the secong XML changes. For example:

<?xml version="1.0" encoding="UTF-8"?>
<data>
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
</data>

depending on the value of the language node (let's call it LANG), a file callled language{LANG}.xml should appended. The content of those files is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<labels>
 <l1001>cliente</l1001>
 <l1002>moneda de referencia</l1002>
</labels>

into something like this:

<?xml version="1.0" encoding="UTF-8"?>
<document>
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
 <labels>
  <l1001>cliente</l1001>
  <l1002>moneda de referencia</l1002>
 </labels>
</document>

And the result of that should be transformed. I have created the following template to do the merge:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:java="http://xml.apache.org/xalan/java/java.lang" xmlns:xfc="http://www.metafocus.no/digiforms/component"&gt;
 <xsl:template match="data">
  <document>
   <xsl:call-template name="copy"/>
   <xsl:variable name="label_file_name" select="concat('Labels_',information/stmtinfo/language,'.xml')"/>
   <xsl:variable name="labels">
    <xsl:copy-of select="document($label_file_name)"/>
   </xsl:variable>
   <xsl:for-each select="xalan:nodeset($labels)/node()">
    <xsl:call-template name="copy"/>
   </xsl:for-each>
  </document>
 </xsl:template>
 <xsl:template name="copy">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

If I user that template, I obtain the following:

<?xml version="1.0" encoding="UTF-8"?><document xmlns:xfc="http://www.metafocus.no/digiforms/component" xmlns:java="http://xml.apache.org/xalan/java/java.lang" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xalan="http://xml.apache.org/xalan"&gt;&lt;data&gt;
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
</data><labels>
 <l1001>cliente</l1001>
 <l1002>moneda de referencia</l1002>
</labels></document>

Which seems correct. But if I invocated from other template, to process the resulting XML

<xsl:template match="/">
 <xsl:variable name="link1">
  <xsl:apply-templates mode="link1" select="node()"/>
 </xsl:variable>
 <xsl:value-of select="xalan:nodeset($link1)"/>
</xsl:template>

I'm obtaining the following

80 2 15907 bogus 1401 Barnacle Street, Miami, Fl

So it seems that the merge does not work correctly, since if I convert the result to a nodeset, the node "labels" disappears. What I'm doing wrong?

Thank you very much.

Jose

A: 

Why are you doing a two-pass transform in the first place? It seems to me that if you just put:

<xsl:variable name="labels" select="document(concat(
   'Labels_', 
   /data/information/stmtinfo/language, 
   '.xml'))"/>

at the top of your document, then you can reference $labels explicitly in your templates. The result of the first pass of your transform isn't different enough in structure from the source XML that you're really gaining anything but complexity from doing it in two passes.

That said, the problem in the transform as written is almost certainly that you're doing this:

<xsl:value-of select="xalan:nodeset($link1)"/>

instead of this:

<xsl:copy-of select="xalan:nodeset($link1)"/>

The value of an element is the concatenation of all of its descendant text nodes, and that's what you're getting in your output.

Robert Rossney
A: 

I simplied the transformation by doing the following:

<xsl:template match="data">
 <xsl:variable name="labels" select="document(concat('Labels_',/data/information/stmtinfo/language,'.xml'))"/>
  <xsl:call-template name="letter-layout"/>
  type=<xsl:value-of select="/data/information/stmtinfo/type"/>
  label=<xsl:copy-of select="$labels/l1001"/>
</xsl:template>

but I'm not getting the label filled.

<?xml version="1.0" encoding="UTF-8"?>
      type=80
      label=

If I don't use the /l1101 I get the following:

<?xml version="1.0" encoding="UTF-8"?>
      type=80
      label=<labels>
    <l1001>cliente</l1001>
    <l1002>moneda de referencia</l1002>
</labels>

So I'm under the impression that the xml imported is being treated as a text, not as a nodeset

Jose L Martinez-Avial