I'm getting a JSON object back from the API and converting that into XML which is all working okay, however when I try to use that converted object and wrapped it in XSL its not rendering any values in the HTML.
Can I do it something like this?
var x2js = new X2JS();
var json2XMLResult = x2js.json2xml_str(data.Results);
this.da = '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="../../../config/Customer.xsl" type="text/xsl" ?> <Results>' + json2XMLResult + '</Results>';
and rendering it using document.getElementById().innerHTML
(<HTMLInputElement>document.getElementById('xmlJson')).innerHTML = this.da;
my XSL file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"
doctype-system="about:legacy-compat"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
Account No. is - <xsl:value-of select="./Results/AccountNumber"/>
Last Name is - <xsl:value-of select="./Results/LastName"/>
</xsl:template>
</xsl:stylesheet>
Can someone point me to the right direction, please. I've never worked on XML nor XSL before so I'm completely lost.
Checking the HTML source it's commenting out the <?xml> tags.
Related
I have been trying out Apache Synapse and been trying to use the JavaScript mediator to set the JSON payload. But the ScriptMessageContext class doesn't contain any method for reading a JSON payload or setting a JSON payload. But there has been numerous examples of setting and getting JSON Payload in WSO2 such as mc.getPayloadJSON(); and mc.setPayloadJSON(response). Is there anyway to workaroud this in Apache Synapse?
I found the answer for myself.Synapse process every data by converting it into soap.So first I needed to convert the flow flie to soap. Then processed the data using javascript and convert the script back to json using xslt.
The complete xml code is shown below.Here I used synapse as proxy to send a get response from another server. then the data from that api is converted to soap and then processed in javascript and converted back from soap to json and send back to client.
<definitions xmlns="http://ws.apache.org/ns/synapse">
<localEntry key="jsonScript" src="file:repository/conf/sample/resources/script/sampleJson.js"/>
<proxy name="SampeJsonProxy">
<target>
<endpoint>
<address uri="http://localhost:8081/kafka/publish/hello" format="json" methods="GET"/>
</endpoint>
<inSequence>
<log level="full"/>
</inSequence>
<outSequence>
<xslt key="in_transform"/>
<property name="messageType" scope="axis2" value="text/xml"/>
<script language="js" key="jsonScript" function="transformResponse"/>
<xslt key="out_transform"/>
<property name="messageType" scope="axis2" value="application/json"/>
<send/>
</outSequence>
</target>
</proxy>
<localEntry key="in_transform">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:m0="http://services.samples" version="2.0" exclude-result-prefixes="m0 fn">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://services.samples">
<xsl:copy-of select="attribute::*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
</localEntry>
<localEntry key="out_transform">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
</localEntry>
</definitions>
I'm getting what appears to me to be a strange error when I load my JSP. Spring is a Java framework, so why would I need a mapping for a JavaScript file? The JavaScript in my page is not working.
org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/ghs1986/js/javascript.js] in DispatcherServlet with name 'ghs1986'
For what it's worth, here is my applicationContext.xml.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<mvc:annotation-driven />
<mvc:resources location="WEB-INF/pages/images/" mapping="/images/**" />
<mvc:view-controller path="/" view-name="home" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
This is how I'm trying to access the JavaScript in my JSPs.
<script type="text/javascript" src="js/javascript.js"></script>
And here is my web.xml.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<web-app version="4.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd">
<display-name>Granada High School Class of 1986</display-name>
<servlet>
<servlet-name>ghs1986</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ghs1986</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
</web-app>
In much the same way as you have a mapping to allow the spring controller to know about images with
<mvc:resources location="WEB-INF/pages/images/" mapping="/images/**" />
you need to add a similar mapping to let it know about your javascript files. Something like,
<mvc:resources location="WEB-INF/pages/js/" mapping="/js/**" />
The issue is the same in both cases, the front end controller of Spring doesn't know how to find your js files without that.
For some browsers, for some clients, jquery suddenly stopped parsing xml.
Example xml:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:example_namespace="https://mylink.com/wfs/example_namespace" xsi:schemaLocation="https://mylink.com/wfs/example_namespace mylink.com?SERVICE=WFS&VERSION=1.0.0&TYPENAME=example_namespace:TABLE&REQUEST=DescribeFeatureType" numberMatched="unknown" numberReturned="1">
<gml:featureMember>
<example_namespace:TABLE fid="TABLE.15">
<example_namespace:ID>15</example_namespace:ID>
</example_namespace:TABLE>
</gml:featureMember>
</wfs:FeatureCollection>
Example jquery
$.get(link, function(data) { //Response is xml like in example.
console.log(data) //works as before
console.log($(data).find("featureMember").find("ID").text())
//Doesn't work now for some clients, but worked before.
})
EDIT:
More general example:
XML
<?xml version="1.0" encoding="UTF-8"?>
<a xmlns:c="http://www.example.com">
<c:b>TEST</c:b>
</a>
AND JS:
console.log($(data).find("b").text())
now returns: "", before returns: "TEST"
EDIT 2:
Similar problem:
Cannot extract SOAP XML with jQuery
This code was originally working in Chrome last week and once Chrome
updated to v60 it no longer does.
Pass data to $.parseXML() to get a #document, use .querySelector()
$.parseXML(data).querySelector("featureMember").querySelector("ID").textContent;
alternatively pass result of $.parseXML() to jQuery() and use .find()
$($.parseXML(data)).find("featureMember").find("ID").text();
jsfiddle https://jsfiddle.net/5fuLquth/
Parsing XML using jQuery in this way has some browser compatibility bugs I believe. This has been a won't fix jquery bug previously.
When there are namespaces in the xml you can use jquery selectors like the below by escaping the colon:
.find('gml\\:featureMember')
or using nodeName:
.find('[nodeName="gml:featureMember"]')
See demo below:
var xml=`<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:example_namespace="https://mylink.com/wfs/example_namespace" xsi:schemaLocation="https://mylink.com/wfs/example_namespace mylink.com?SERVICE=WFS&VERSION=1.0.0&TYPENAME=example_namespace:TABLE&REQUEST=DescribeFeatureType" numberMatched="unknown" numberReturned="1"><gml:featureMember><example_namespace:TABLE fid="TABLE.15"><example_namespace:ID>15</example_namespace:ID></example_namespace:TABLE></gml:featureMember></wfs:FeatureCollection>`;
console.log($(xml)
.find('gml\\:featureMember')
.find("example_namespace\\:ID").text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am currently trying to implement a function to sort a XML file by the attribute of one of its nodes.
The way to go seemed to be using XSLT to transform the XML file and by researching a bit I managed to put together a working XSLT file (validated in some online-validator, output was as would be expected).
After I got the results I wanted, I started implementing JavaScript functions to do this automatically every time it is required. Ultimately a chart (amCharts) will be created using the data from the XML file. To generate that chart properly, the data has to be sorted though.
Right now everything seems to work syntax-wise, however, the XSLTProcessor and/or XMLSerializer seem to have problems parsing/combining both the XML and XLST file.
Strangely enough Firefox also throws an error: Component returned failure code: 0x80600001 [nsIXSLTProcessor.importStylesheet]
Chrome doesn't seem to have this problem.
But this is not the main issue. The result generated contains a rudimental HTML page saying that there was an error, but giving no exact error description/location/explanation whatsoever.
I expected to see the sorted XML file here, just as in the online XML/XSLT validator, which had the same inputs XML/XSLT content wise.
Does anyone have an idea regarding the source of this issue? Would greatly appreciate any hints and/or solutions to this.
best regards,
daZza
Edit
After researching the "Extra content at the end of the document" error on the generated page more in-depth (and having overlooked it when I posted the OP), it seems that the error is triggered when there are more than one root elements in the XML file, which would obviously be wrong.
However, the source XML files do not have multiple root nodes and are all perfectly valid.
This leads me to believe that the XSLT reordering/sorting of the source file is not done as expected, although it looked good in the XSLT validator.
I guess somehow it produces multiple root nodes instead of just reordering the item nodes within the root node?
Unfortunately I am no expert regarding XSLT so it would be awesome, if someone with a more detailed knowledge could especially look at the XSLT code.
Edit2
I think I might have solved the problem by changing the XSLT query slightly. I am getting a proper looking output for Chrome and Firefox, but IE still throws an error (did I mention that I hate cross-browser compatibilities? -.-).
Further testing is still required, but at least it's a progress. Still appreciating any hints regarding the topic though.
Code:
XML Sample Snippet (removed content, the "" parts are filled in the real file):
<?xml version="1.0" encoding="utf-8"?>
<root>
<item Art="" LinkTitle="" Eindruck="" Bereich="" Unterbereich="" Priority="" Handlungsma_x00df_nahme="" Status_x0020_der_x0020_Ma_x00df_="" Aufwand="" Benefit="" Termin_x0020_der_x0020_Retrospek="" Produkt="" Release="" />
<item Art="" LinkTitle="" Eindruck="" Bereich="" Unterbereich="" Priority="" Handlungsma_x00df_nahme="" Status_x0020_der_x0020_Ma_x00df_="" Aufwand="" Benefit="" Termin_x0020_der_x0020_Retrospek="" Produkt="" Release="" />
</root>
XSLT file
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:choose>
<xsl:when test="*[local-name()='item']">
<xsl:apply-templates select="#* | node()">
<xsl:sort select="#Unterbereich" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="#* | node()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
JavaScript function
function sortXML()
{
var parser = new DOMParser();
// xml and xsl are correctly filled with the data from their appropriate files
// via AJAX GET requests earlier in the code
var domToBeTransformed = xml;
var xslt = xsl;
var processor = new XSLTProcessor();
processor.importStylesheet(xslt);
var newDocument = processor.transformToDocument(domToBeTransformed);
var serializer = new XMLSerializer();
var newDocumentXml = serializer.serializeToString(newDocument);
alert(newDocumentXml);
}
Currently generated document (var newDocumentXml)
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<parsererror style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black">
<h3>This page contains the following errors:</h3>
<div style="font-family:monospace;font-size:12px">error on line 1 at column 1: Extra content at the end of the document</div>
<h3>Below is a rendering of the page up to the first error.</h3>
</parsererror>
</body>
</html>
Firstly, I would re-jig your XSLT to avoid the use of xsl:choose. There is no point in testing if a child element exists if you are already matching an attribute or text node. It may be better (and cleaner, with less indentation) to use separate templates.
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[*[local-name()='item']]">
<xsl:copy>
<xsl:apply-templates select="#*" />
<xsl:apply-templates select="node()">
<xsl:sort select="#Unterbereich" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The first thing to note is that you specified a version of "2.0" in your XSLT. Microsoft (and so IE) does not natively support XSLT 2.0. However, in this case, you are not using any XSLT 2.0 features, so changing it to XSLT 1.0 should not be a problem (Of course, if your actual XSLT does need to use 2.0, then that is a whole separate question!)
But I don't think this is an issue with your XSLT any more, but more an issue with how transformation is done in the browser with javascript. The code you have given will only work in Chrome and Firefox (and Opera, I think). IE doesn't support those commands, and has its own methods. And to compound matters further, IE10 and above do things differently to previous versions!
Anyway, I headed over to Object doesn't support property or method 'transformNode' in Internet Explorer 10 (Windows 8) and found a good sample of JavaScript. Try re-jigging your JavaScript to this:
function sortXML()
{
if (typeof (XSLTProcessor) != "undefined")
{
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
var resultDocument = xsltProcessor.transformToDocument(xml);
var serializer = new XMLSerializer();
var newDocumentXml = serializer.serializeToString(resultDocument);
alert(newDocumentXml);
}
else if (typeof (xml.transformNode) != "undefined")
{
var ex = xml.transformNode(xsl);
alert(ex);
}
else
{
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
xslDoc.load(xsl);
var xslt = new ActiveXObject("Msxml2.XSLTemplate");
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = xml;
xslProc.transform();
alert(xslProc.output);
}
}
Am trying to call javascript from within my XSL file, but it is not working..
Wanted to know:
1. Is there any problem with my XSL file... (see below)
2. Is there any system configuration to be done before running XSL with Javascript?
IE 9.0 is being used for testing of this prototype XSL.
Here is the content of XSL file :
<?xml version='1.0' ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:lxslt="http://xml.apache.org/xslt"
xmlns:result="http://www.example.com/results"
extension-element-prefixes="result" >
<xsl:output method="html" indent="yes"/>
<lxslt:component prefix="result" functions="myParse">
<lxslt:script lang="javascript">
function myParse()
{
return "just testing....";
}
</lxslt:script>
</lxslt:component>
<xsl:template match="/">
<xsl:for-each select="comment/MyObject">
<xsl:variable name="temp" select="#objectInformation" />
<xsl:variable name="temp2">
<xsl:value-of>
<script type="text/javascript">
result:myParse()
</script>
</xsl:value-of>
</xsl:variable>
<xsl:value-of select="string($temp2)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I believe the syntax for calling your function in this case would be:
<xsl:value-of select="result:myParse()" />
Or you could just do this in this case:
<xsl:variable name="temp2" select="result:myParse()" />
And are you sure that the namespace in this case shouldn't be http://xml.apache.org/xalan?