I have the Java method ...
public static Object parseXMLtoXLSX(File xmlFile, String path)
So I want to call the method from XSLT.
I understand, that I have to introduce the class in my XSLT File e.g. like this:
<xsl:stylesheet version="2.0" xmlns:trans="pathToMyJavaClass">
But how can I call the method?
Is this the right way?:
<xsl:value-of select="trans:parseXMLtoXLSX($xmlFIle,$path)" />
But how can I store the Java File Object, that I get back from the Method in a Variable?
Edit: I can't show the < > in this question...
The calling conventions from XSLT to other languages depend entirely on which XSLT processor you are using, so you need to provide this information.
If you're using XSLT 2.0 under Java then it's likely that the processor you are using is Saxon, in which case the calling conventions are documented at http://saxonica.com/documentation/index.html#!extensibility/functions
In cases where you're handling objects (like a Java java.util.File) that have no equivalent in the XDM data model used by XSLT, the calling conventions can be quite complicated. It's simpler if you organize things so that you only need to pass simple values like strings and integers. For example, write another method in Java that accepts a String (containing a file name) rather than a File.
Related
I am learning XSLT and I see some codes like the following:
<node id="{java:next($idgen)}:state" pred="should" mood="dcl">
where next is a java function. What are the curly braces used for?
Besides I am quite confused at how java functions are called in XSLT. In my sample code, XSLT just calls java functions like above without specifying the location of the java class file, even the class name is not specified.
What are the curly braces used for?
The curly braces have nothing to do with Java. They indicate to the processor that the contents are to be evaluated as an expression - see: https://www.w3.org/TR/xslt/#attribute-value-templates
Besides I am quite confused at how java functions are called in XSLT.
That depends on your specific processor. Calling Java functions is not part of the XSLT standard, and only some processors support it as an extension.
You have shown a literal result element with an attribute value template where the XPath expression inside the attribute value template uses some XSLT processor specific mechanism to call a Java method of the variable $idgen.
I am getting following code in response in xml
<.........>
<stsuuser:Attribute name="authorized" type="urn:ibm:names:ITFIM:oauth:response:decision">
<stsuuser:Value>TRUE</stsuuser:Value>
</stsuuser:Attribute>
<.........>
Now how I can get <stsuuser:Value> is true or false using Java?
There are quite literally dozens of libraries for Java that parse XML. But, I find JOOX by far the simplest to use. It lacks quite a few common features of other libraries, but unlike them, it's a joy to use. It provides you with a jQuery-like API (even has the $ function) and, in your case, you'd use it as follows:
import static org.joox.JOOX.$;
...
//Get the value of "authorized" attribute
$(...).xpath("//Attribute[#name='authorized']/Value").text();
The $ function will accepts a String, a file, a stream, a reader etc, so you can initialize with pretty much anything.
What I am trying to achieve is (using Saxon-B 9.1):
1) Run XSLT transformation with object of below Example class as parameter
2) Object's properties are populated using reflexive extension function with selected Nodes
3) Run second XSLT transformation (on different XML input) and pass the above object with populated values as parameter
4) Insert XML nodes from the object into output document
My class is below:
public class Example {
. private NodeSet test;
. public RequestInfo() {}
. public void settest(NodeList t) {
. this.test = t;
. }
. public NodeList gettest() {
. return test;
. }
}
First transformation seems to populate my object fine (using settest() method within XSLT) - I can see correct nodes added to the NodeList.
However, I am getting below error when running 2nd transformation and calling gettest() method from within XSLT:
NodeInfo returned by extension function was created with an incompatible Configuration
I was thinking should I not use NodeList but maybe some different, equivalent type that would be recognised by Saxon? I tried it with NodeSet but got same error message.
Any help on this would be appreciated.
You haven't shown enough information to see exactly what you are doing wrong, but I can try and explain the error message. Saxon achieves its fast performance in part by allocating integer codes to all the names used in your XML documents and stylesheets, and using integer comparisons to compare names. The place where the mapping of integers to names is held is the NamePool, and the NamePool is owned by the Saxon Configuration object; so all documents, stylesheets, etc participating in a transformation must be created under the same Configuration (it's a bit like the DOM rule that all Nodes must be created under the Document they are attached to). The message means that you've got at least two different Configuration objects around. A Configuration gets created either explicitly by your application, or implicitly when you create a TransformerFactory, an XPathFactory, or other such objects.
I wonder whether this mixing of XSLT and Java code is really a good idea? Often when I see it, the Java code is being used because people haven't mastered how to achieve the desired effect in XSLT. There are many good reasons for NOT using the DOM with Saxon: it's very slow, it requires more lines of code, it's not thread-safe, it's harder to debug, ...
I am writing a Java client that communicates with a remote server via HTTP/XML.
Server sends commands to my client in XML format, like this:
<command>
<name>C1</name>
<param>
.....
</param>
</command>
There is about 10 or more different commands (C1, C2, ...), each of them has different set of params.
My client will process the command, then response server with a execute result, looks like this:
<C1>
<code>200</code>
<desc>xxx</desc>
</C1>
I am only familiar with C, but very new to Java and OOP,
so, my question is simple, how to design the following logic gracefully in a OOP way?
1.Convert the XML string to an XML Object
2.Find correspoding executor based on 'name' element of the XML, and parse the params
3.Execute the command along with the params
4.Convert the result to an XML Object
5.Convert the XML Object to an XML string
Is this a good design?
1.Define an abstract base class and many sub-classes for each command, which include the following method:
void parseCommand(MyXMLObject obj);
void execute();
MyXMLObject generateResult();
or just a simple method:
MyXMLObject execute(MyXMLObject obj);
and these fields:
String mCommandName;
int mRetCode;
String mRetDesc;
2.Then define a factory class to return an instance of one of the sub-classes based on the XML Object.
3.The logic part code:
MyXMLObject obj = MyXMLUtil.getXMLObject(XMLString);
MyCommand command = MyCommandFactory.getCommand(obj);
MyXMLObject retObj = command.execute();
String retStr = MyXMLUtil.getString(retObj);
...//network operation
Generally speaking, it is a good design (you probably need more interfaces and such, and there are various refinements).
The greater problem is that this is, in many ways, a reinvention of the wheel. There are numerous frameworks that handle mapping from POJOs (java objects) to structured textual formats (such as XML or JSON). On top of that, there are many general implementations of command frameworks. It might be worth investigating available options before you provide your own implementation.
In principle, yes, that's how things work. But I think you should separate the different concerns.
Basically I'd say you have a service layer that needs to execute commands and return the results. This layer should know nothing about XML, so I'd design the plain Java Object model and then worry about tying it to your XML infrastructure, probably using an existing XML mapping technology like XStream.
As the others said, the design looks pretty good. To make your life easier, you should have a look at Simple XML to parse XML -> Java and to create XML from Java objects.
Are there any tools available for transforming types defined in an xsd schema (may or may not include other xsd files) into ActionScript value objects? I've been googling this for a while but can't seem to find any tools and I'm pondering wether writing such a tool would save us more time right now than to simply code our value objects by hand.
Another possibility I've been considering is using a tool such as XMLBeans to transform the types defined by the schema to Java classes and then converting those classes in ActionScript. However, I've come to realize that there are about a gazillion java -> as3 converters out there and the general consesus seems to be that they sort of work, ie, I have no idea which tool is a good fit.
Any thoughts?
For Java -> AS generation, check out GAS3 from the Granite Data Services project:
http://www.graniteds.org/confluence/display/DOC/2.+Gas3+Code+Generator
This is the kind of thing you can write yourself too, especially if you leverage a tool like Ant and write a custom Task to handle it. In fact, I worked on this last year and open-sourced it:
https://github.com/cliffmeyers/Java2As
I don't have any kind of translator either. What I do is have an XML object wrapped by an ActionScript object. Then you have a getter/setter for each value that converts xml->whatever and whatever->XML. You still have to write the getter/setter though, but you can have a macro/snippit handle that work for you.
So for XML like:
<person>
<name>Bob</name>
...
</person>
Then we have an XML Object Wrapper class and extend it. Normally
class XMLObjectWrapper
{
var _XMLObject:XML;
function set XMLObject(xml:XML):void
{
_XMLObject = xml;
}
function get XMLObject():XML
{
return _XMLObject;
}
}
class person extends XMLObjectWrapper
{
function set name(value:String):void
{
_XMLObject.name = value;
}
function get name():String
{
return _XMLObject.name;
}
}