i have a problem with XSLT...
<xsl:text> </xsl:text>
Then after generation, for some reason the resulting JSP file produces a '?' instead. What's wrong?
My recent system changes:
I changed Java5 -> Java6
Weblogic -> Weblogic12
Eclipse Ganymede -> Oracle Pack Eclipse
EDIT 1: <xsl:output method="xml"/>, encoding=UTF-8
The original XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="common.xsl"/>
<xsl:output method="xml"/>
...
<xsl:template name="makeLink">
<xsl:variable name="fieldtype" select="name()"/>
<xsl:variable name="currentNode"><xsl:value-of select="generate-id()"/></xsl:variable>
<xsl:variable name="appendSpace">
<xsl:for-each select="ancestor::ButtonList[position() = 1]/descendant::Button">
<xsl:if test="generate-id() = $currentNode and position() > 1">true</xsl:if>
</xsl:for-each>
</xsl:variable>
<a href="{$url}">
<xsl:attribute name="id">btn_<xsl:value-of select="Action"/></xsl:attribute>
<xsl:call-template name="populateAttributes">
<xsl:with-param name="fieldtype">
<xsl:value-of select="$fieldtype"/>
</xsl:with-param>
</xsl:call-template>
<xsl:copy-of select="#class"/>
<xsl:copy-of select="#style"/>
<xsl:text><span><span></xsl:text><xsl:value-of select="$buffer"/><xsl:text></span></span></xsl:text>
</a>
<xsl:if test="not(#omitWhiteSpace)">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="ReadOnly and ReadOnly != 'someReadOnlyMethod'
and ReadOnly != 'someReadyOnlyMethod'
and ReadOnly != ''">
<xsl:text></c:if></xsl:text>
</xsl:if>
</xsl:template>
....
Transformed (after XSLT), and resulting JSP page:
<%# page contentType = "text/html;charset=GBK"%>
<%# page isELIgnored = "false"%>
<%# page language="java"
import=" my.controller.*, my.core.config.*, my.core.datastructure.*, my.core.error.*, my.core.util.*,
my.service.Constants, my.service.modulesvr.ModuleBean, myW.sn.*, java.util.Locale, java.util.Map"%>
<%# taglib uri="http://www.mycompany.com/my/tags/htmltag-10" prefix="html"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%MySn mySession = (MySn) session.getValue("MySn"); QuickSearchController mb = (mySession == null) ? null : (QuickSearchController)
mySession.getModuleBean(); String sessionToken = mySession.getSessionToken(); String htmlCharSet = mySession.getEncoding();
MyUsr user = mySession.getMyUsr(); String[] result; Object o;%>
.........
<span><span>NEW PROP</span></span> </c:if>
EDIT 2: it seems like if i use <xsl:text> </xsl:text> instead of <xsl:text> </xsl:text>...the problem seems to have gone away. In the JSP, it will appear as   and on the browser, it is seen as a no-break space, which is expected.
That often happens if your encoding is wrong. What encoding are you writing your output in? How are you serving up the page? Possibly you are serializing in UTF-8 but trying to display in ISO-8859-1 (or Windows-1252), or vice-versa.
Check to see if the default encoding somewhere has changed.
Just because you say <xsl:output method="xml" encoding="UTF-8"/> doesn't mean that the program will honor it. Is the XSLT embedded in a piece of Java? Does the Java control the streams/readers/writers?
If you can save a portion of the file and dump it in HEX, you should quickly be able to find out. If you see 0xC2 0xA0 then your file is indeed in UTF-8. However, if you just see 0xA0 alone, then you are in ISO-8859-1 or one of its close relations.
It's also possible that the page is being rendered properly, but the page is being served up with the wrong encoding. Can you look at the headers returned, perhaps by using Firebug in Firefox or in Chrome "Web Developer->Information->View Response Headers" or by using the IE debug tools.
Related
I have a problem. I think it is simple but I havent found it.
like below code I want to find and match multiplier factor value like "0.05" with "005" in the note value dynamically and take text "AAA" after "_ 005 _"(without spaces) and write it and others too.
I tried to use together both format number and concatenate to "concat(format-number(***))" but failed because of newby about this.
<cbc:Note>40.00 BT</cbc:Note>
<cbc:Note>17_ 2005.00</cbc:Note>
<cbc:Note>11_005_AAA</cbc:Note>
<cbc:Note>11_002_BBB</cbc:Note>
<cbc:Note>11_003_CCC</cbc:Note>
<cbc:InvoicedQuantity unitCode="CS">1.000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="TRY">200.00</cbc:LineExtensionAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:MultiplierFactorNumeric>0.03</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="TRY">6.00</cbc:Amount>
<cbc:BaseAmount currencyID="TRY">200.00</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:MultiplierFactorNumeric>0.05</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="TRY">10.00</cbc:Amount>
<cbc:BaseAmount currencyID="TRY">200.00</cbc:BaseAmount>
</cac:AllowanceCharge>
current xslt block
<xsl:for-each select="./cac:AllowanceCharge/cbc:MultiplierFactorNumeric">
<br/>
<xsl:text> %</xsl:text>
<xsl:value-of select="format-number(. * 100, '###.##0,00', 'european')"/>,
</xsl:for-each>
I appreciate if you help me.
It is very difficult to understand your question.
The following minimal example is mostly based on a guess. It formats the MultiplierFactorNumeric value as a 3-digit whole number and uses it as a key to retrieve the corresponding Note value:
XML
<root>
<Note>40.00 BT</Note>
<Note>17_ 2005.00</Note>
<Note>11_005_AAA</Note>
<Note>11_002_BBB</Note>
<Note>11_003_CCC</Note>
<AllowanceCharge>
<MultiplierFactorNumeric>0.03</MultiplierFactorNumeric>
</AllowanceCharge>
<AllowanceCharge>
<MultiplierFactorNumeric>0.05</MultiplierFactorNumeric>
</AllowanceCharge>
</root>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="note" match="Note" use="substring-before(substring-after(., '_'), '_')" />
<xsl:template match="/root">
<result>
<xsl:for-each select="AllowanceCharge">
<item>
<factor>
<xsl:value-of select="MultiplierFactorNumeric"/>
</factor>
<value>
<xsl:value-of select="substring-after(substring-after(key('note', format-number(100*MultiplierFactorNumeric, '000')), '_'), '_')"/>
</value>
</item>
</xsl:for-each>
</result>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<result>
<item>
<factor>0.03</factor>
<value>CCC</value>
</item>
<item>
<factor>0.05</factor>
<value>AAA</value>
</item>
</result>
XML I was given
<root>
<page>0</page>
<totalRecords>74</totalRecords>
<totalPages>1</totalPages>
<offset>0</offset>
<status>success</status>
<entityList>
<ENAME>
<ADAMS>
</ENAME>
<DNAME>&RESEARCH</DNAME>
<JOB>CLERK</JOB>
<EMPNO>7876</EMPNO>
<HIREDATE>1987-05-23 "00: 00 ":00.0</HIREDATE>
<LOC>DALLAS</LOC>
</entityList>
<entityList>
<ENAME>>ALLEN</ENAME>
<DNAME>&SALES</DNAME>
<JOB>SALESMAN</JOB>
<EMPNO>7499</EMPNO>
<HIREDATE>1981-02-20 00:00:00.0</HIREDATE>
<LOC>CHICAGO</LOC>
</entityList>
<entityList>
<ENAME>Abhi></ENAME>
<DNAME>&SALES</DNAME>
<JOB>PRU</JOB>
<EMPNO>7956</EMPNO>
<HIREDATE></HIREDATE>
<LOC>CHIC"AGO "</LOC>
</entityList>
</root>
MY XSLT block thus far
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="no" omit-xml-declaration="yes" />
<xsl:template match="root">
{
"page":<xsl:value-of select="//page"/>,
"totalRecords":<xsl:value-of select="//totalRecords"/>,
"totalPages":<xsl:value-of select="//totalPages"/>,
"offset":<xsl:value-of select="//offset"/>,
"status":"<xsl:value-of select="//status"/>",
"entityList":[<xsl:for-each select="entityList">
{
"ENAME":"<xsl:value-of select="translate(ENAME,'<,>','')"/>",
"DNAME":"<xsl:value-of select="replace(DNAME,'&','')"/>",
"JOB":"<xsl:value-of select="JOB"/>",
"EMPNO":"<xsl:value-of select="EMPNO"/>",
"HIREDATE":"<xsl:value-of select="replace(HIREDATE,'"','')"/>",
"LOC":"<xsl:value-of select="replace(LOC,'"','')"/>"
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
}
</xsl:template>
</xsl:stylesheet>
Do I use the replace function or do I use translate? On here I see people use variables but I am new to XSLT and am just learning everything.
I need to remove the '&', the '<>', and the quotes in the hire date along with all other special characters in the XML
Please assist with pointers and tips as you can. Thank you.
There is no replace() function in XSLT 1.0; it was introduced in 2.0.
You can remove special characters using translate(), for example translate(., '&', '').
But what do you really want to do? Why are you trying to remove these characters? It looks as if you're trying to output JSON, in which case the way to handle these characters correctly is simply to use <xsl:output method="text"/>.
I've inherited a project that wants to use xslt to transform some html. Matching works with '/', but I can't get it to run on a subnode
I've found some code snippet on mozilla, that applies xslt transformation to html on mozilla, the code works https://developer.mozilla.org/en-US/docs/Web/XSLT/XSLT_JS_interface_in_Gecko/Advanced_Example.
The Problem is that I'm not able to template match the node "firmenliste"
What I use is:
var xslRef;
var xslloaded = false;
var xsltProcessor = new XSLTProcessor();
var myDOM;
var xmlRef = document.implementation.createDocument("", "", null);
p = new XMLHttpRequest();
p.open("GET", "xsl/FirmenListe.xsl",false);
p.send(null);
xslRef = p.responseXML;
xsltProcessor.importStylesheet(xslRef);
xmlRef = document.implementation.createDocument("", "", null);
// we want to move a part of the DOM from an HTML document to an XML document.
// importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
var myNode = document.getElementById("example");
var clonedNode = xmlRef.importNode(myNode, true);
// after cloning, we append
xmlRef.appendChild(clonedNode);
var fragment = xsltProcessor.transformToFragment(xmlRef, document);
// clear the contents
document.getElementById("example").innerHTML = "";
myDOM = fragment;
// add the new content from the transformation
document.getElementById("example").appendChild(fragment)
The corresponding html and xslt looks like:
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<firmenliste></firmenliste>
</data>
</xml>
<?xml version ='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
b
<xsl:apply-templates select="firmenliste"/>
</xsl:template>
<xsl:template match="firmenliste">
A
</xsl:template>
</xsl:stylesheet>
The output should be
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
bA
</data>
</xml>
But what i get is
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
b
</data>
</xml>
Edit: The problem is reproducible in https://next.plnkr.co/edit/Yvc59BPQmI1PHlSy?open=lib%2Fscript.js&preview
I think the main problem is that you start with elements in a HTML DOM document which since HTML5 are by definition in the XHTML namespace http://www.w3.org/1999/xhtml and then clone and copy them to an XML document where they keep their namespace but where in XSLT/XPath a path or match pattern like firmenliste selects or matches elements of that name in no namespace and not in the XHTML namespace.
So using
<xsl:template match="/">
b
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="xhtml:firmenliste" xmlns:xhtml="http://www.w3.org/1999/xhtml">
A
</xsl:template>
instead would fix that problem: https://next.plnkr.co/edit/tsB9qwCafLodg8Rz?open=lib%2Fscript.js&preview
But the whole approach of using non-defined elements like xml or firmenliste in HTML and moving between HTML DOM and XML DOMs is asking for trouble in my experience. Consider to keep the XML data you want to transform outside of the HTML document in a separate XML document, only use XSLT on XML documents and only use its transformation result to be inserted into an HTML DOM if you have used transformToFragment with the owning HTML document as the second argument.
In your xslt, while matching root node with '/', You need to give whole xPath to match <firmenliste> in <xsl:apply-templates>
Try the same by replacing the line <xsl:apply-templates select="firmenliste"/>
with <xsl:apply-templates select="/xml/data/firmenliste"/>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
b
<xsl:apply-templates select="/xml/data/firmenliste" />
</xsl:template>
<xsl:template match="firmenliste">
A
</xsl:template>
</xsl:stylesheet>
I have an XML file as follows:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.xslt"?>
<results>
<test name="sentence1">
<description href="#ömr">
ömr1, ämr1, ümr1 and pär1
</description>
</test>
<test name="sentence2" href="#pär2">
<description>
ömr2, ämr2, ümr2 and pär2
</description>
</test>
<test name="sentence3" href="#pär3">
<description>
ömr3, ämr3, ümr3 and pär3
</description>
</test>
</results>
Then here is the XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://www.froglogic.com/XML2"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="Summary/test">
<html>
<body>
<xsl:for-each select="//test">
<xsl:variable name="linkMe" select="#name"/>
<xsl:value-of select="description"/>
<a href="#{$linkMe}" >
<xsl:value-of select="$linkMe" />
</a>
<xsl:value-of select="description"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
I want to convert the XML to an HTML file using Perl. But it's going to have not desired output although I have told Perl I want output as a UTF-8.
The perl code is like this:
use strict;
use warnings;
use XML::LibXML;
use XML::Writer;
use XML::LibXSLT;
use XML::Parser;
use Encode qw( is_utf8 encode decode );
my $XML_File = "test2.xml";
my $XSLT_File = "test2.xslt";
my $HTML_File = "test2.html";
sub XML2HTML {
my $xml_parser = XML::LibXML->new('1.0', 'UTF-8');
my $xslt_parser = XML::LibXSLT->new('1.0', 'UTF-8');
my $xml = $xml_parser->parse_file($XML_File);
$xml->setEncoding('UTF-8');
my $xsl = $xml_parser->parse_file($XSLT_File);
my $stylesheet = $xslt_parser->parse_stylesheet($xsl);
my $results = $stylesheet->transform($xml);
my $output = $stylesheet->output_string($results);
$stylesheet->output_file($results, $HTML_File);
}
&XML2HTML($XML_File, $XSLT_File, $HTML_File);
Another question is how I could have UTF-8-BOM output as file? I searched the internet and could not find an exact answer. They all mention UTF-8 rather than UTF-8-BOM.
The HTML output seems unpleasant:
ömr1, ämr1, ümr1 and pär1 ömr2, ämr2, ümr2 and pär2 ömr3, ämr3, ümr3 and pär3
The encoding format in HTML is
Codepage 1252(Western)
and it is strange!
First, you have a subroutine which operates on global variables. That is not a good idea. Instead, those values as arguments to the function so your function is not tied to names you use in other places in your program.
Second, you do not do anything with $output, but storing the output in it will still increase the memory footprint of your program.
Third, looking at the underlying XS code for write_file, we see:
xsltSaveResultToFilename(filename, doc, self, 0);
And, xsltSaveResultToFilename is documented here. Looking at the source code for xsltSaveResultToFilename, we note that the routine deduces the output encoding from the stylesheet. So, the problem has to lie elsewhere.
It turns out, my initial diagnosis was incorrect. After getting my hands on a system with the necessary libraries, I ran your script (which revealed syntax errors in your XSL file -- don't post code we cannot run). After fixing those, I realized the code was producing UTF-8 encoded output, but the HTML did not include a declaration of document encoding. Therefore, when I viewed in my browser, it tried to use Windows 1252. Your XSL template needs to declare the encoding of the HTML document as well. Of course, if add the BOM, you probably don't need the declaration in the head of the document.
The following script seems to work for me:
use strict;
use warnings;
use autouse Carp => 'croak';
use File::BOM ();
use XML::LibXML;
use XML::LibXSLT;
xml_to_html('test.xml', 'test.xsl', 'test.html');
sub xml_to_html {
my ($xml_file, $xsl_file, $html_file) = #_;
open my $out, '>:unix', $html_file
or croak "Failed to open '$html_file': $!";
print $out $File::BOM::enc2bom{'UTF-8'}
or croak "Failed to write UTF-8 BOM: $!";
my $xslt_parser = XML::LibXSLT->new;
my $xml_parser = XML::LibXML->new;
my $xml = $xml_parser->parse_file( $xml_file );
my $xsl = $xml_parser->parse_file( $xsl_file );
my $style = $xslt_parser->parse_stylesheet( $xsl );
my $results = $style->transform( $xml );
$style->output_fh( $results, $out );
return;
}
with this template:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://www.froglogic.com/XML2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>,
</head>
<body>
<xsl:for-each select="//test">
<xsl:variable name="linkMe" select="#name"/>
<xsl:value-of select="description"/>
<a href="#{$linkMe}" >
<xsl:value-of select="$linkMe" />
</a>
<xsl:value-of select="description"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and produces the following output:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns:b="http://www.froglogic.com/XML2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">,
</head>
<body>
ömr1, ämr1, ümr1 and pär1
sentence1
ömr1, ämr1, ümr1 and pär1
ömr2, ämr2, ümr2 and pär2
sentence2
ömr2, ämr2, ümr2 and pär2
ömr3, ämr3, ümr3 and pär3
sentence3
ömr3, ämr3, ümr3 and pär3
</body>
</html>
I have
$ pacman -Ss libxslt
extra/libxslt 1.1.29+42+gac341cbd-1 [installed]
XML stylesheet transformation library
which does not seem to include support for generating HTML5 doctype.
Depending on your specific needs, you may have to tweak the XSLT file further.
i am converting docx file into html using xslt. My resulting html contains styles like margin-top:NaN pt;, the style value NaN is ignored in browser by default.But i have to validate for the presence of such attributes and have to remove before viewing in browser...
Please help me...Thanks in advance...
Have you tried W3C CSS validator?
http://jigsaw.w3.org/css-validator/
You can use it programatically thanks to a SOAP Web service:
http://jigsaw.w3.org/css-validator/api.html
You should check for 'NaN' before adding inline styles.
E.g. consider this XML:
<?xml version="1.0"?>
<t>
<Number>adsfdasf</Number>
<Number></Number>
<Number>100</Number>
<Number>1.234234</Number>
</t>
Then you can:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Number">
<xsl:value-of select="concat(., ' : ')"/>
<xsl:if test="not(string(number()) = 'NaN')">valid</xsl:if>
<xsl:if test="string(number()) = 'NaN'">invalid</xsl:if>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Result:
adsfdasf : invalid
: invalid
100 : valid
1.234234 : valid
It is too-late to chack for NaN in the generated result.
Producing unwanted output should be prevented!
Here is an example, that avoids generating NaN:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num[number(.) = number(.)]">
<span style="margin-top:{.}"/>
</xsl:template>
<xsl:template match="num[not(number(.) = number(.))]"/>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<t>
<num>helo</num>
<num></num>
<num>100</num>
<num>1.234234</num>
</t>
only correct output (no NaN) is produced:
<t>
<span style="margin-top:100"/>
<span style="margin-top:1.234234"/>
</t>