problem with XSLT - xslt

I am trying to create a html based template with xslt transformation.The string result returned by the transformer is perfectly fine.but when i try to send it to display, the browser is not interpreting it. The output looks like<html><body>...</body></html>.
when i do view source it is displaying <html>... How can i resolve it?Please help.
Thanks in advance

Did you specify the output method correctly? It should be set to HTML:
<xsl:output method="html" encoding="UTF-8" />

<xsl:output value="html"/>
<xsl:template match="mail[#type='pinReset']">
<html><body>
<xsl:variable name="userService" select="java:new()"/>
<i><u>Message body </u><xsl:value-of select="mailMessage/mail/body/prefix"/></i>
<a><xsl:attribute name="href">
<xsl:value-of select="java:getResetPinUrl($userService)"/></xsl:attribute>
reset pin
</a>
<i><xsl:value-of select="mailMessage/body/suffix"/></i><br/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
This is my XSl.
public String getXformedString(int type){
String xFormedString = "";
String xsltFile = "D:\\SitesContent\\sitescontent_war\\JavaSource\\com\\tgt\\mobile\\gc\\controller\\email.xsl";
String xmlFile="D:\\SitesContent\\sitescontent_war\\JavaSource\\com\\tgt\\mobile\\gc\\controller\\emailBody.xml";
StringWriter stWr = new StringWriter();
File xsltfile = new File(xsltFile);
File xmlfile = new File(xmlFile);
Source xmlSource = new StreamSource(xmlfile);
Source xsltSource = new StreamSource(xsltfile);
Result result = new StreamResult(stWr);
TransformerFactory transFact = TransformerFactory.newInstance();
try {
Transformer transformer= transFact.newTransformer(xsltSource);
transformer.setParameter("type",new Integer(type));
transformer.transform(xmlSource, result);
xFormedString = stWr.toString();
System.out.println("Str->"+xFormedString);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return xFormedString;
}
This is the code to get the formed string from xml and xslt.

Related

Is there a way to remove namespaces from xml tags using C++/Boost or using some other library

Is there a way in C++, using Tinyxml , TinyXpath , such that, a string containing :
<ns:abcd>
<ns:defg>
<ns:hijk>
</ns:hijk>
</ns:defg>
</ns:abcd>
transforms to
<abcd>
<defg>
<hijk>
</hijk>
</defg>
</abcd>
EDIT:
I was using Tinyxml and Tinyxpath.
My workflow was :
a) Create a dom-tree using TinyXML
b) Pass dom-tree to Tinyxpath for xpath evaluations
To add namespace removal, I used following function :
void RemoveAllNamespaces(TiXmlNode* node)
{
TiXmlElement* element = node->ToElement();
if(!element){
return;
}
std::string elementName = element->Value();
std::string::size_type idx = elementName.rfind(':');
if(idx != std::string::npos)
{
element->SetValue(elementName.substr( idx + 1).c_str());
}
TiXmlNode* child = element->IterateChildren(NULL);
while(child)
{
RemoveAllNamespaces(child);
child = element->IterateChildren(child);
}
}
So workflow changed to :
a) Create a dom-tree using TinyXML
b) Remove namespace from the domtree using RemoveAllNamespaces(domtree.Root() )
c) Pass modified-dom-tree to Tinyxpath for xpath evaluations
I would employ an XSLT transform here:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="*">
<xsl:element name="{name()}" namespace=""><xsl:apply-templates select="node()|#*"/></xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{name()}" namespace=""><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Note that on elements/attribute, namespace="" clears the namespace. You can also specify a different namespace instead.
With input.xml like
<?xml version="1.0"?>
<ns:abcd xmlns:ns="http://bla/bla">
<ns:defg attr="value">
<ns:hijk>
</ns:hijk>
</ns:defg>
</ns:abcd>
xsltproc xform.xsl input.xml prints:
<abcd>
<defg attr="value">
<hijk>
</hijk>
</defg>
</abcd>
Ok, in response to the edited question, a few notes:
that doesn't actually treat the namespaces (consider xmlns="http://blabla.com/uri" style default namespaces), but that's actually a TinyXml limitation (eek):
Further, TinyXML has no facility for handling XML namespaces. Qualified element or attribute names retain their prefixes, as TinyXML makes no effort to match the prefixes with namespaces.
it doesn't treat attributes (which can also be qualified)
Here's what I'd do a quick & dirty (assumes TIXML_USE_STL as you were supposedly already using):
static inline std::string RemoveNs(std::string const& xmlName)
{
return xmlName.substr(xmlName.find_last_of(":") + 1);
}
void RemoveAllNamespaces(TiXmlNode* node)
{
assert(node);
if (auto element = node->ToElement()) {
element->SetValue(RemoveNs(element->Value()));
for (auto attr = element->FirstAttribute(); attr; attr = attr->Next())
attr->SetName(RemoveNs(attr->Name()));
for (auto child = node->IterateChildren(nullptr); child; child = element->IterateChildren(child))
RemoveAllNamespaces(child);
}
}
On my MSVC test it prints
<?xml version="1.0" standalone="no"?>
<!-- Our: to do list data -->
<ToDo a="http://example.org/uri1">
<!-- Do I need: a secure PDA? -->
<Item priority="1" distance="close">Go to the<bold>Toy store!</bold></Item>
<Item priority="2" distance="none">Do bills</Item>
<Item priority="2" distance="far & back">Look for Evil Dinosaurs!</Item>
</ToDo>

pass xml variable into c# method in xslt

i have xslt transform where im using c# code to save input and output xml to database.
but it saves only the values of all tags.
but i want to save vhole xml.
<msxsl:script language="CSharp" implements-prefix="ConnectDatabase">
<msxsl:assembly name = "System.Data"/>
<msxsl:using namespace = "System.Data"/>
<msxsl:using namespace = "System.Data.SqlClient"/>
<msxsl:using namespace = "System.Collections.Generic"/>
<![CDATA[
public void LogINOUT(string inputxml, string outputxml)
{
SqlCommand cmd = null;
string command = "INSERT INTO dbo.XsltLog (InputXml,OutputXml) VALUES (#inputxmlpar,#outputxmlpar)";
string connectionString ="Data Source=MyConneCtionStiring;
SqlParameter inputxmlpar = new SqlParameter("#inputxmlpar", SqlDbType.NVarChar);
inputxmlpar.Value=inputxml;
SqlParameter outputxmlpar = new SqlParameter("#outputxmlpar", SqlDbType.NVarChar);
outputxmlpar.Value =outputxml;
using (SqlConnection connection = new SqlConnection(connectionString))
{
cmd = new SqlCommand(String.Format(command), connection);
cmd.Parameters.Add(inputxmlpar);
cmd.Parameters.Add(outputxmlpar);
connection.Open();
cmd.ExecuteScalar();
}
}
]]></msxsl:script>
then a call it <xsl:copy-of select ="ConnectDatabase:LogINOUT( $inputxml,$outputxml)" />
and outputxml in database is something like this:
TO_TESTY45000.0000000020
from this string i know nothing
i wont its
<Data>
<Result>TO_TEST</Result>
<IncludeInVolume>Y</IncludeInVolume>
<FinancedAmont>
<xsl:value-of select="/Contract/ContractCalculations/Calculation/CalculationStep[#Code='FinancedAmount']"/>
</FinancedAmont>
<NumberOfInstalments>
<xsl:value-of select="format-number(/Contract/ContractCalculations/Calculation/CalculationStep[#Code='InstalmentNumber'],'#')"/>
</NumberOfInstalments>
</Data>
the same problem its with inputxml
thanks for Help Dana

xalan and custom function for xslt

I'm using Apache FOP with the IKVM from my c# code. I generate the pdf by using the xslt stylesheet to get the result as xsl fo. I have one problem, that is usingthe custom functions.
My stylesheet declaration:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:cal="xalan://m.test"
extension-element-prefixes="cal"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema-instance http://www.xmlblueprint.com/documents/fop.xsd">
The custom function:
namespace m
{
public class test
{
public static string zzz(ExpressionContext x, object d)
{
return "test";
}
}
}
And calling this from the xslt:
<xsl:value-of select="cal:zzz(1)"/>
Code to compile it:
FopFactory fopFactory = FopFactory.newInstance();
fopFactory.ignoreNamespace("http://www.w3.org/2001/XMLSchema-instance");
fopFactory.setUserConfig(new File("fop.xconf"));
OutputStream o = new DotNetOutputMemoryStream();
try
{
Fop fop = fopFactory.newFop("application/pdf", o);
TransformerFactory factory = TransformerFactory.newInstance();
Source xsltSrc = new StreamSource(new File("data.xsl"));
Transformer transformer = factory.newTransformer(xsltSrc);
var bytes = System.IO.File.ReadAllBytes("data.xml"); //"HR_CV.fo");
var stream = new DotNetInputMemoryStream(new System.IO.MemoryStream(bytes));
Source src = new StreamSource(stream);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
}
finally
{
o.close();
}
Exception I got is:
java.lang.NoSychMethodExtension: For extension function, could not find method org.apache.xml.utils.NodeVector.zzz([ExpressionContext,])
What I'm doing wrong?
You're calling the zzz function with a single argument (1). But your function expects two arguments. If you provide both arguments, chances are it will work just fine.

XPath in PHPUnit testing with Zend

I have this apparently basic code:
$docSrc =
'<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title /></head>
<body><p>Test paragraph.</p></body>
</html>';
$domDoc = new DOMDocument();
$domDoc->loadXML($docSrc);
$xpath = new DOMXPath($domDoc);
$nodeList = $xpath->query('//p');
$this->assertTrue($nodeList->length == 1);
It should succeed, but fails miserably, the length is 0. I have been looking for a solution all day, but to no avail.
Wow thanks! It works! Unfortunately, my original code:
$query = new Zend_Dom_Query($docSrc);
$xpathQuery = '//p';
$result = $query->queryXpath($xpathQuery);
$this->assertTrue($result->count() == 1);
thinks it is an XML and perform loadXML. Do you have any idea why this happens?
Ok I found the culprit somewhere in the Zend Library:
if ('<' . '?xml' == substr(trim($document), 0, 5)) {
return $this->setDocumentXml($document, $encoding);
}
I wonder if this is correct since it IS an XML document, but load XML does not work.
Ok I’m doing some research. Apparently, the problem has something to do with namespaces...
Change line 2 to:
$domDoc->loadHTML($docSrc);
There IS a bug, workaround is:
$docSrc =
'<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title /></head>
<body><p>Test paragraph.</p></body>
</html>';
$domDoc = new DOMDocument();
$domDoc->loadXML($docSrc);
$xpath = new DOMXPath($domDoc);
$xpath->registerNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
$nodeList = $xpath->query('//xhtml:p');
$this->assertTrue($nodeList->length == 1);

Runtime error with tinyXML element access

yester day was my first attempt. I am trying to catch the variable "time" in the following "new.xml" file
<?xml version="1.0" standalone=no>
<main>
<ToDo time="1">
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
<Item priority="2"> Do bills</Item>
</ToDo>
<ToDo time="2">
<Item priority="1"> Go to the Second<bold>Toy store!</bold></Item>
</ToDo>
</main>
Here is my code
TiXmlDocument doc("new.xml");
TiXmlNode * element=doc.FirstChild("main");
element=element->FirstChild("ToDo");
string temp=static_cast<TiXmlElement *>(element)->Attribute("time");
But I am getting run time errors from the third and fourth lines. Can anybody shed a light on this isssue?
It seems to me that you forgot to load the file. Normally I do something along these lines:
TiXmlDocument doc("document.xml");
bool loadOkay = doc.LoadFile(); // Error checking in case file is missing
if(loadOkay)
{
TiXmlElement *pRoot = doc.RootElement();
TiXmlElement *element = pRoot->FirstChildElement();
while(element)
{
string value = firstChild->Value(); // In your example xml file this gives you ToDo
string attribute = firstChild->Attribute("time"); //Gets you the time variable
element = element->NextSiblingElement();
}
}
else
{
//Error conditions
}
Hope this helps
#include "tinyXml/tinyxml.h"
const char MY_XML[] = "<?xml version='1.0' standalone=no><main> <ToDo time='1'> <Item priority='1'> Go to the <bold>Toy store!</bold></Item> <Item priority='2'> Do bills</Item> </ToDo> <ToDo time='2'> <Item priority='1'> Go to the Second<bold>Toy store!</bold></Item> </ToDo></main>";
void main()
{
TiXmlDocument doc;
TiXmlHandle docHandle(&doc);
const char * const the_xml = MY_XML;
doc.Parse(MY_XML);
TiXmlElement* xElement = NULL;
xElement = docHandle.FirstChild("main").FirstChild("ToDo").ToElement();
int element_time = -1;
while(xElement)
{
if(xElement->QueryIntAttribute("time", (int*)&element_time) != TIXML_SUCCESS)
throw;
xElement = xElement->NextSiblingElement();
}
}
That's how it works. Compiled & tested.
As you can see your tries to make it extra-safe code cost you with an exceotion at your third line (of the question), and without testing I can bet it's a "pointing-to-null" exception.
Just load it my style, as TinyXml's docs say as well: "docHandle.FirstChild("main").FirstChild("ToDo").ToElement();".
Hope it helps you understand, let me know if it's not clear. I accept visa (:
Is it just me or the the pugixml version looks much better?
#include <iostream>
#include "pugixml.hpp"
using namespace std;
using namespace pugi;
int main()
{
xml_document doc;
if (!doc.load_file("new.xml"))
{
cerr << "Could not load xml";
return 1;
}
xml_node element = doc.child("main");
element = element.child("ToDo");
cout << "Time: " << element.attribute("time") << endl;
}
Also new.xml had an error, instead of:
<?xml version="1.0" standalone=no>
should be
<?xml version="1.0" standalone="no"?>
Compilation was just a matter of cl test.cpp pugixml.cpp