RE: [xsl] XML 2 CSV using XLS with HTML-Tags inside + double quote

Subject: RE: [xsl] XML 2 CSV using XLS with HTML-Tags inside + double quote
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 12 Nov 2007 09:16:05 -0000
A couple of points:

(a) "CSV" is a very generic term, you need to explain what you are actually
trying to generate. There are no standards for CSV, so you can't rely on
people knowing what you want to do. In your case it seems to be
semicolon-separated rather than comma-separated. Trying to reverse-engineer
the requirements from your non-working code suggests that you want to put
quotes around a field that contains a semicolon, and if a quoted field
contains a quote you want to escape it with a backslash. It would be useful
to see the actual input and the actual output.

(b) With method=text, special characters are never escaped so
disable-output-escaping is unnecessary and has no effect.

(c) If you're getting "&lt;" in the output where you want "<", then it's
probably because the input was double-escaped (perhaps as "&amp;lt;",
perhaps as <!CDATA[&lt;]]>). You haven't shown the input so we can only
guess.

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: eddie_s@xxxxxx [mailto:eddie_s@xxxxxx] 
> Sent: 12 November 2007 00:08
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] XML 2 CSV using XLS with HTML-Tags inside + 
> double quote
> 
> Hello @ all,
> 
> first: excuse me for my bad english - i hope you will 
> understand me ;-). 
> It's been a while ago since i wrote a longer text ^^.
> 
> Now it's 2 years ago since i was working with XSLT and XML - 
> but the last week i mostly got back into it. My profession is 
> more XHTML + CSS.
> 
> To the problem:
> - i read the FAQ (all the FAQ's i found)
> - used searchengines
> to solve my "little" problem.
> 
> There are two systems. AuktionMaster and Yatego. Our products 
> are listed in the Database of AuktionMaster. Now i want to 
> get them to another marketplace > Yatego.
> 
> There's an option to generate a Eport-Format using XSL. With 
> this XSL i can generate a CSV File. I need this CSV file, 
> because Yatego only imports ;-separated CSV-Files. Ok - i 
> thought - no problem. Well it's frustrating :-(.
> 
> My XSL:
> <?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
> version="1.0">
> <xsl:output method="text" media-type="text/comma-separated-values" 
> version="1.0" indent="yes" encoding="ISO-8859-1" />
> <!-- this must be meinly correct i think -->
> 
> <!-- fields needed -->
> <xsl:template match="/">
> <xsl:text>foreign_id;article_nr;title;tax;price;price_uvp;pric
e_purchase;tax_differential;basic_price;units;delivery_surcharge>
;delivery_calc_once;short_desc;long_desc;url;auto_linefeet;pic
> ture;picture2;picture3;picture4;picture5;categories;variants;d
> iscount_set_id;stock;delivery_date;cross_selling;delitem;statu
> s;top_offer</xsl:text>
> 		<xsl:text>&#xD;&#xA;</xsl:text>
> 		<xsl:apply-templates select="export/item"/> 
> </xsl:template>
> 
> <xsl:template match="export/item">
>    <xsl:choose>
>      <xsl:when test="inventory_active='1'"><!-- i check if 
> product is set flag active -->
> 
>      ... now i catch the fields needed with the fields from the source
> 
> 	<xsl:value-of select="item_id" /> <!-- for example 
> product number -->
> 	<xsl:text>;</xsl:text>
> 
>      ... well, i've got the field names from an other XSL 
> inside of that back-end. So i don't know which 
> version/processor of XSL they use (sorry)
> 
>      .... ok - i get the fields mainly by <xsl:value-of 
> select="name" />
> 
> Now we came to the product description, which is stored with 
> HTML inside the DB. If i use
> 
> <xsl:value-of select="description_table/description" 
> disable-output-escaping="yes" />
> 
> the HTML Code with instyle CSS <p style="font: 9pt Arial, 
> sans-serif;">This Product is ...</p> and a lot other HTML 
> Tags like <div>, <img>, <ul> ... is breaking inside the 
> CSV-File on the place of the ";" (semicolon). Viewing the 
> file with Excel one part of the HTML Code is inside the field 
> "long_desc" an the rest inside the other fields. So the 
> CSV-File is not correct.
> 
> Nearby with method="text" disable-output-escaping="yes" is 
> not working (i read it in the FAQ).
> 
> Then i found a lot of Tepmplates how to get the HTML Code 
> inside this one field through escaping quotes.
> 
> So i used
> 
> <xsl:text>&quot;</xsl:text>
>    <xsl:apply-templates select="description_table/description" 
> mode="escape-CSV" />
> <xsl:text>&quot;</xsl:text>
> <xsl:text>;</xsl:text>
> 
> ... rest of the XSL:
> 
>       <xsl:text></xsl:text>
>       <xsl:text>;</xsl:text>
>     <xsl:text>&#xD;&#xA;</xsl:text><!-- line break here -->
>    </xsl:when>
>   </xsl:choose>
> </xsl:template>
> 
> Here's the Template for escaping the quotes. It worked. But 
> now it doesn't. I don't know why. I never changed it. It's 
> like i found it on the net.
> 
> <xsl:template match="node()" mode="escape-CSV" name="escape-CSV">
>     <xsl:param name="string" select="." />
>     <xsl:choose>
>        <xsl:when test="contains($string, '&quot;')">
>           <xsl:value-of select="substring-before($string, 
> '&quot;')" />
>           <xsl:text>\"</xsl:text>
>           <xsl:call-template name="escape-CSV">
>              <xsl:with-param name="string"
>                    select="substring-after($string, '&quot;')" />
>           </xsl:call-template>
>        </xsl:when>
>        <xsl:otherwise>
>           <xsl:value-of select="$string" />
>        </xsl:otherwise>
>     </xsl:choose>
> </xsl:template>
> 
> Ok i know i'll get it back to work - but the main problem is 
> is: After escaping the html-code it shows inside the CSV 
> &lt;p&gt; ... . Because the CSV is going to be importet in 
> Yatego i need to replace the field
> (string) and get the < and > back. So i tried and tried. And 
> i didn't get it. I know the problem isn't much big - but i 
> need the "Aaaaaah"-Effect to go on :-).
> 
> Here is one of the ideas i tried:
> 
> 
> 1.
> <xsl:template match="node()" mode="escape_special_characters" 
> name="escape_special_characters">
>    <xsl:param name="input_text" select="." />
> <!-- http://www.w3schools.com/xsl/el_param.asp -->
>      <xsl:variable name="step_1">
>        <xsl:call-template name="replace_quot">
>          <xsl:with-param name="input_text" select="." />
> 	  </xsl:call-template>
>      </xsl:variable>
>      <xsl:value-of select="$step_1" />
> </xsl:template>
> 
> 2.
> <xsl:template name="replace_lt">
> 	<xsl:param name="input_text" />
> 	<xsl:param name="special_char" />
> 	<xsl:choose>
> 		<xsl:when test="contains($input_text, $special_char)">
> 			<xsl:value-of 
> select="substring-before($input_text, $special_char)" />
> 				<xsl:text>&lt;</xsl:text>
> 			<xsl:value-of select="$special_char" />
> 				<xsl:call-template name="replace_lt">
> 					<xsl:with-param 
> name="input_text" 
> select="substring-after($input_text, $special_char)" />
> 					<xsl:with-param 
> name="special_char" select="$special_char" />
> 				</xsl:call-template>
> 		</xsl:when>
> 		<xsl:otherwise>
> 			<xsl:value-of select="$input_text" />
> 		</xsl:otherwise>
> 	</xsl:choose>
> </xsl:template>
> 
> ...
> 
> I think my main problem is not the recursive part it's the 
> basic part of calling the template:
> 
> <xsl:apply-templates select="description_table/description" 
> mode="escape-CSV" />
> 
> I don't know how to get all the templates to work or how 
> correctly to call them for:
> 
> - 1. double quote the HTML-Code to get something linke 
> "&lgt;p&gt; ... "
> - 2. replace &lt; with < and &gt; with > to get correct HTML 
> Code inside the CSV
> - 3. to import the CSV into Yatego to get the product 
> description displayed correctly in the browser.
> 
> Thank you all very very much for all kind of help.
> 
> Greetings
> Eddie

Current Thread