ORAEXT : XPST0017: Cannot find a matching 5-argument function named - java

While doing XSLT transformation, I have a requirement to call Datasource inside xsl. I am using ora-ext to achieve it. But I am getting Cannot find a matching 5-argument function named and 4-argument matching function on use of the query-database function of ORAEXT.
Full stacktrace:
Static error at char 1 near {...t_code','jdbc/JDBCDataSourc...} in expression in xsl:value-of/#select on line 1 column 1575
XPST0017: Cannot find a matching 5-argument function named
{http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc}lookup-table().For diagnostics on calls to Java methods, use the -TJ command line option or set the Configuration property FeatureKeys.TRACE_EXTERNAL_FUNCTIONS
This is my XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:sql="http://ns.saxonica.com/sql"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:java="http://saxon.sf.net/java-type"
xmlns:saxon="http://saxon.sf.net/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ora="http://schemas.oracle.com/xpath/extension"
exclude-result-prefixes="java saxon xsd xsi xsl sql"
extension-element-prefixes="saxon sql"
>
<xsl:template match="Order">
<Parameter>
<xsl:attribute name="name">ACT_CODE</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="oraext:lookup-table('ACT_CODE_MTDT', 'prdt_id','1159', 'act_code','jdbc/JDBCDataSource')"/>
</xsl:attribute>
</Parameter>
</xsl:template>
</xsl:stylesheet>
Kindly suggest, if I am missing on something. Suggest me if any jar apart from ojdbc6.jar is required.
Also, I'm not able access this URL.
Is that the namespace got changed, or there something missing in my code.

It looks to me as if you are running Saxon as your XSLT processor (we can tell from the form of the error messages) but you are trying to call an extension function that has been defined by Oracle as an vendor extension for their own XSLT processor. That ain't gonna work.

Related

keep only wanted elements in xml with the given list of xpath

I have some complex xml structure. Some times i want to keep only the elements match my runtime list of xpath entries.
Sample xml
<Employee>
<Address>
<addressLine1>Dummy Line 1</addressLine1>
<zip>535270</zip>
</Address>
<Department>
<id>102</id>
<name>development</name>
</Department
</Employee>
Sample xpath entries can be some time like
//Employee/Address
//Employee/Department/
//Employee/Department/name
In the above xpath if you observe we have Department and Name inside department then in that case I can ignore Department.Also above xpath entries can be as below too
//Employee/Address
//Employee/Department/name
Resultant xml i want as below
<Employee>
<Address>
<addressLine1>Dummy Line 1</addressLine1>
<zip>535270</zip>
</Address>
<Department>
<name>development</name>
</Department
</Employee>
I realized I can achieve this through xslt. So I want the xslt for this kind of generic requirement. Also my current code is in java. Is there any better alternative in java??
I have to admit that I do not fully understand your requirements, but what I do see is that:
You have a set of XPath
You seem to want to get the union of these XPath statements if applied to your input document
Duplicates removed (just like XPath union expression)
Some magic about certain elements that may appear even if they are not in the XPath statement list.
My original reflex was: use xsl:evaluate, but considering you are rooting all your XPath expressions, this may not give you the results you want. Also, it requires an XSLT 3.0 processor.
With XSLT 2.0, you could do something like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:variable name="patterns" as="xs:string*">
<xsl:sequence select="(
'foo/bar',
'foo/test',
'foo/bar/zed')" />
</xsl:variable>
<xsl:template match="node()[true() = (
for $p in $patterns
return ends-with(
string-join(current()/ancestor-or-self::*/name(),
'/'), $p))]">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
It is just meant to get you started, it is not meant as a full-fledged solution. It matches XPath of the production //QName/QName, like the one in your example. I removed the trailing //, and simply match when the current path matches any of the paths (taking into account an implicit descendent-or-self, as in your example).
You probably want to wrap the for-expression in a function and call the function to map the concatenation of the current path to any of your paths in your list.
In its current form, you will also need to supply the paths leading up to a deeper path, or you will have to implement an fn:snapshot-like function to copy the ancestor nodes as well.
Anyway, I think this is a simple enough approach to mimic not necessarily xsl:evaluate, but mimic pattern matching based on a path, as your question seems to imply.

Java SAX parsing: What's wrong with this XML?

I'm trying to validate an XML file, but I get the following error:
Can not find declaration of element
'xsl:stylesheet'.
This is the XML:
<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl' xmlns:ns='http://www.ibm.com/wsla'>
<xsl:strip-space elements='*'/>
<xsl:output method='xml' indent='yes'/>
<xsl:template match='#* | node()'>
<xsl:copy>
<xsl:apply-templates select='#* | node()'/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ns:SLA/ns:ServiceDefinition/ns:WSDLSOAPOperation/ns:SLAParameter/#name[.='TotalMemoryConsumption']">
<xsl:attribute name='{name()}'>
<xsl:text>MemConsumption</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Where is the mistake?
EDIT: I want to parse this XML in Java with SAX, but I get the following error:
Element type "xsl:template" must be followed by either attribute specifications, ">" or "/>".
How to get rid of it?
Assuming you are actually trying to validate your XSL as an XML document, it looks like that website requires you to point to a schema or DTD in order to validate the XML against it. You can get a non-normative schema here: http://www.w3.org/TR/xslt20/#schema-for-xslt. Here's instructions on how to reference a schema from an XML file: http://www.ibm.com/developerworks/xml/library/x-tipsch.html
You could also check "Well-Formedness only," and check the document for well-formedness, if not actually validity.
Generally, any XSL engine will report any errors in your XSL document, so you don't need to validate it separately.
Your XSL is OK, don't worry. Just that there is no DTD/XSD for XSLs 1.0. no one bothers checking XSLT stylesheets (1.0) for validity. "Wellformedness" is enough.

Removing elements from an XML document, XSLT and JAXB

This question is a follow up to my earlier question:
Creating a valid XSD that is open using <all> and <any> elements
Given that I have a Java String containing an XML document of the following form:
<TRADE>
<TIME>12:12</TIME>
<MJELLO>12345</MJELLO>
<OPTIONAL>12:12</OPTIONAL>
<DATE>25-10-2011</DATE>
<HELLO>hello should be ignored</HELLO>
</TRADE>
How can I use XSLT or similar (in Java by using JAXB) to remove all elements not contained in a set of elements.
In the above example I am only interested in (TIME, OPTIONAL, DATE), so I would like to transform it into:
<TRADE>
<TIME>12:12</TIME>
<OPTIONAL>12:12</OPTIONAL>
<DATE>25-10-2011</DATE>
</TRADE>
The order of the elements is not fixed.
This transformation:
<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:param name="pNames" select="'|TIME|OPTIONAL|DATE|'"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*/*">
<xsl:if test="contains($pNames, concat('|', name(), '|'))">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<TRADE>
<TIME>12:12</TIME>
<MJELLO>12345</MJELLO>
<OPTIONAL>12:12</OPTIONAL>
<DATE>25-10-2011</DATE>
<HELLO>hello should be ignored</HELLO>
</TRADE>
produces the wanted, correct result:
<TRADE>
<TIME>12:12</TIME>
<OPTIONAL>12:12</OPTIONAL>
<DATE>25-10-2011</DATE>
</TRADE>
Explanation:
The identity rule (template) copies every node "as-is".
The identity rule is overridden by a template matching any element that is not the top element of the document. Inside the template a check is made if the name of the matched element is one of the names specified in the external parameter $pNames in a pipe-delimited string of wanted names.
See the documentation of your XSLT processor on how to pass a parameter to a transformation -- this is implementation-dependent and differs from processor to processor.
I haven't tried yet, but maybe the javax.xml.tranform package can help:
http://download.oracle.com/javase/6/docs/api/javax/xml/transform/package-summary.html
JAXB & XSLT
JAXB integrates very cleanly with XSLT for an example see:
How to get jaxb to Ignore certain data during unmarshalling
Your Other Question
Based on your previous question (see link below), the transform is really unnecessary as JAXB will just ignore attributes and elements that are not mapped to fields/properties in your domain object.
Creating a valid XSD that is open using <all> and <any> elements

Remove special characters from XML via XSLT only for specific tags

I am having a certian issue with special characters in my XML.
Bascially I am splitting up an xml into multiple xmls using Xalan Processor.
When splitting the documents up I am using their value of the name tag as the name of the file generated. The problem is that the name contains characters that arent recognized by the XML processor like ™ (TM) and ® (R). I want to remove those characters ONLY when naming the files.
<xsl:template match="products">
<redirect:write select="concat('..\\xml\\product\\en\\',translate(string(name),'</> ',''),'.xml')">
The above is the XSL code I have writter to split the XML into multlpe XMLs. As you can see I am using hte translate method to subtitute '/','<','>' with '' from the name. I was hoping I could do the same with ™ (TM) and ® (R) but it doesnt seem to work.
Please advice me how I would be able to do that.
Thanks for you help in advance.
I don't have Xalan, but with 8 other XSLT processors this thransformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()">
<xsl:value-of select="translate(., '</>™®', '')"/>
===================
<xsl:value-of select="translate(., '</>™®', '')"/>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<t>XXX™ My Trademark®</t>
produces the wanted result:
XXX My Trademark
===================
XXX My Trademark
I suggest that you try to use one of the two expressions above -- at least the second may work successfully.
Following Dimitre answer, I think that if you are not sure about wich special character could be in name, maybe you should keep what you consider legal document's name characters.
As example:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()">
<xsl:value-of select="translate(.,
translate(.,
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ',
''),
'')"/>
</xsl:template>
</xsl:stylesheet>
With input:
<t>XXX™ My > Trademark®</t>
Result:
XXX My Trademark

How can I transform a functional language in XML to Java?

I'm working with a DSL based on an XML schema that supports functional language features such as loops, variable state with context, and calls to external Java classes. I'd like to write a tool which takes the XML document and converts it to, at the very least, something that looks like Java, where the <set> tags get converted to variable assignments, loops get converted to for loops, and so on.
I've been looking into ANTLR as well as standard XML parsers, and I'm wondering whether there's a recommended way to go about this. Can such an XML document be converted to something that's convertable to Java, if not directly?
I'm willing to write the parsing through SAX that writes an intermediate language based on each tag, if that's the recommended way, but the part that's giving me pause is the fact that it's context-based in the same way a language like Scheme is, with child elements of any tag being fully evaluated before the parent.
You can do it with XSLT. Then just use to generate the code snippets you need.
(remember to set the output format to plain text)
EDIT: Sample XSLT script
Input - a.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="b.xsl"?>
<set name='myVar'>
<concat>
<s>newText_</s>
<ref>otherVar</ref>
</concat>
</set>
Script - b.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="text" />
<xsl:template match="set">
<xsl:value-of select="#name"/>=<xsl:apply-templates/>
</xsl:template>
<xsl:template match="concat">
<xsl:for-each select="*">
<xsl:if test="position() > 1">+</xsl:if>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="ref">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="s">
<xsl:text>"</xsl:text>
<xsl:apply-templates/>
<xsl:text>"</xsl:text>
</xsl:template>
</xsl:stylesheet>
Note that a.xml contain an instruction that will let XSLT-capable browsers render it with the stylesheet b.xsl. Firefox is such a browser. Open a.xml in firefox and you will see
myVar="newText_"+otherVar
Note that XSLT is a quite capable programming language, so there is a lot you can do.

Categories