Environment: eXist-db 4.2.1 , XQuery 3.1, XSLT 2.0
In eXist-db I am loading an XSLT file which includes a reference to a collection in eXist (in order to perform a search on documents found there, using a key). This reference seems to throw an error from Saxon.
Exception while transforming node: Exception thrown by URIResolver
XML docs are located at /db/apps/deheresi/data/
XSLT docs are located at /db/apps/deheresi/data/styles
In the transform function, I am passing a parameter from XQuery to the XSLT file for the absolute path to the data folder:
<param name="paramDatauri"
value="xmldb:exist:///db/apps/deheresi/data/"/>
In the XSLT file, this parameter is received and injected into a variable:
<xsl:variable name="coll"
select="collection(concat($paramDatauri,'?select=*.xml'))"/>
I've looked at possible parameters that Saxon might need, but I've not identified any that can resolve this problem.
EDIT #1: I've tried to pass an attribute in XQuery transform()
<attributes>
<attr name="paramSax" value="COLLECTION_URI_RESOLVER"/>
</attributes>
per Saxonica documentation, but I get the message
`Unable to set up transformer: Unknown configuration property`
I don't know if this is redundant/unnecessary, or if I've configured the attribute incorrectly.
EDIT #2: I've attempted to hardcode the absolute path into the XSL file:
<xsl:variable name="coll"
select="collection('xmldb:exist:///db/apps/deheresi/data/?select=*.xml')"/>
As well a relative path:
<xsl:variable name="coll"
select="collection('/db/apps/deheresi/data/?select=*.xml')"/>
Always returning the same error Exception thrown by URIResolver.
This is the first time I've tried to use a collection() function within a XSLT within eXist-db.
Many thanks.
Related
I'm trying to send a quite simple JSON message from BizTalk.
{
"Value": 1
}
I set the type of the "Value" field to xs:int in my xml schema
<xs:element minOccurs="1" maxOccurs="1" name="Value" type="xs:int" />
But it keeps generating the wrong JSON message.
{
"Value": "1"
}
Not sure what I'm doing wrong here. Does anybody have some tips?
There can be multiple issues at work here.
Your XML payload is not going through a XML Dissasembler or Assembler before reaching the JSON Encoder, and hence the Message Type isn't set correctly, in which case it is not using the schema to determine the correct date types.
You have another earlier element in your schema with the same name but a different type. It will use the type from the first one for all elements with the same name. This was a bug in BizTalk 2013 R2, and I think it was still there in BizTalk 2016 and could cause some strange errors, especially if you had a Records (complex types) and Element (simple types) with the same name. e.g FIX: JSON encoder unable to handle XML schema with the same name for record and one of its elements in CU 7
Biztalk Embedded JSON Encoder has the ability to recognize schema of XML processed and should recognize xs:int value from schema and encoded without quotes.
But sometimes (as Sandro Pereira indicates even often) this encoder throws the error:
Reason: Value cannot be null.
Parameter name: key
That was my case. I had to use a custom JSON Encoder that recognizes XML datatype somehow.
My solution was:
Use this build of Newtonsoft.Json library that uses json:Type argument as indicator of XML tag datatype.
Create a custom JSON Encoder that uses the previous library
Create custom Complex Type in separate schema with targetNamespace = "http://james.newtonking.com/projects/json"
Note that attribute Type need to be Qualified
Import above schema in Your target schema using prefix json
Use this type as Data Structure Type and rename Your parameter.
Map this checking logical existance, to avoid putting argument without value or custom xslt tranform
Usefull sites:
Adding name to attribute
i am working on oracle SOA project in which i want to save csv data to XML file. till now i got the payload in form of xml using Translate activity but i can only use it directly. I want to save the pay load to xml file.
i am facing following error :
<?xml version="1.0" encoding="UTF-8"?><bpelFault>
<faultType>0</faultType>
<subLanguageExecutionFault xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable">
<part name="summary">
<summary>An error occurs while processing the XPath expression; the expression is ora:doXSLTransformForDoc("../Transformations/Transformation.xsl", $Receive_Read_InputVariable.body)</summary>
</part>
<part name="code">
<code>XPath expression failed to execute</code>
</part>
<part name="detail">
<detail>XPath expression failed to execute.
An error occurs while processing the XPath expression; the expression is ora:doXSLTransformForDoc("../Transformations/Transformation.xsl", $Receive_Read_InputVariable.body)
The XPath expression failed to execute; the reason was: javax.xml.transform.TransformerException: oramds:/deployed-composites/default/CSV_To_XML_rev1.0/Transformations/Transformation.xsl<Line 30, Column 109>: XML-22031: (Error) Variable not defined: 'oracle_empty_param'.
Check the detailed root cause described in the exception message text and verify that the XPath query is correct.
</detail>
</part>
</subLanguageExecutionFault>
</bpelFault>
I am working with oracle soa suite 12c.
It sounds like you want to convert a variable to a string. I would use an XSL transform. Input to the transform would be your newly translated variable and the output be a plain old String variable. The transform would look like this:
<xsl:template match="/">
<tns:myString>
<xsl:copy-of select="/ns0:RootElement"/>
</tns:myString>
</xsl:template>
If you wanted to, you could then write this string to the file adapter
I'm trying to use the "Convert XML to JSON" example from WikiBooks here https://en.wikibooks.org/wiki/XQuery/Convert_XML_to_JSON
xquery version "3.0";
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:media-type "application/json";
let $test := <root>
<!-- simple elements -->
<aaa>AAA</aaa>
<bbb>BBB</bbb>
<ccc>CCC</ccc>
<!-- complex (nested) element -->
<ddd>
<eee>
<fff>
<ggg>GGG</ggg>
</fff>
</eee>
</ddd>
<!-- duplicate elements -->
<hhh>HHH1</hhh>
<hhh>HHH2</hhh>
<hhh>HHH3</hhh>
<hhh>HHH4</hhh>
<!-- attributes -->
<iii a1="123" a2="456" a3="789"/>
<!-- attributes with text content-->
<jjj a1="123" a2="456" a3="789">JJJ</jjj>
</root>
return $test
I'm using the Saxon parser, with this command line
java -cp Saxon-HE-9.8.0-8.jar net.sf.saxon.Query xml2json.xqy
But it's still returning the $test variable as xml, what am I missing?
The wikibook article you reference is incorrect. According to the relevant specification, XSLT and XQuery Serialization 3.1, the JSON serialization method treats XML nodes as follows:
A node in the data model instance is serialized to a JSON string by outputting the result of serializing the node using the method specified by the json-node-output-method parameter. The node is serialized with the serialization parameter omit-xml-declaration set to yes and with no other serialization parameters set.
In other words, an XQuery processor like Saxon is supposed to serialize XML nodes as JSON strings.
To achieve the goal promised by the wikibook article, you would need to transform the document into maps and arrays or into an intermediary format that you can feed to the xml-to-json()` function.
How do I solve the
Reference to undeclared namespace prefix: '%s'
problem with Microsoft's msxml implementation?
I'm using an XML feed from a government web-site that contains values i need to parse. The xml contains namespaces:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3c.org/1999/02/22-rdf-syntax-ns#rdf.xsd">
<item rdf:about="http://www.bankofcanada.ca/stats/rates_rss/STATIC_IEXE0101.xml">
<cb:statistics>
<cb:exchangeRate>
<cb:value decimals="4">1.0351</cb:value>
<cb:baseCurrency>CAD</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Bank of Canada noon rate</cb:rateType>
<cb:observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
</rdf:RDF>
Running the XPath query:
/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency
fails with the error:
Reference to undeclared namespace prefix: 'rdf'
Edit:
If i edit the original XML to remove all use of namespaces:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf>
<item>
<statistics>
<exchangeRate>
<value decimals="4">1.0351</value>
<baseCurrency>CAD</baseCurrency>
<targetCurrency>USD</targetCurrency>
<rateType>Bank of Canada noon rate</rateType>
<observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</observationPeriod>
</exchangeRate>
</statistics>
</item>
</rdf>
The query /rdf/item/statistics/exchangeRate/baseCurrency doesn't fail, and returns nodes:
<baseCurrency>CAD</baseCurrency>
How do i get Microsoft XML to work with namespaces?
Edit 2
i've tried adding SelectionNamespaces to the DOMDocument object:
doc.setProperty('SelectionNamespaces', 'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');
Now the xpath query doesn't fail, but it also returns no nodes:
nodes = doc.selectNodes('/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency');
See also
“undeclared reference to namespace prefix ” error
XMLReader - How to handle undeclared namespace
PRB: Specifying Fully Qualified Element Names in XPath Queries
XPath not working properly.
Using SelectionNamespaces is the correct approach, you are just missing a namespace.
Notice that your XML document explicitly sets the default namespace as follows:
xmlns="http://purl.org/rss/1.0/"
This means that any element without a prefix, such as the item element, is actually in the default namespace. So if you want to select that element with an XPath expression, you must first set an appropriate selection namespace.
To do this, you can change your call to setProperty like so:
doc.setProperty('SelectionNamespaces', 'xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');
Here you've assigned the default namespace from the document to the rss: prefix in your XPath expression. With that change in place, the following XPath expression should work correctly:
nodes = doc.selectNodes('/rdf:RDF/rss:item/cb:statistics/cb:exchangeRate/cb:targetCurrency');
It works because it references the item element using the correct namespace. The fact that the prefix differs between the XPath expression and the original document is immaterial. It is the namespace which the prefix is bound to that matters.
doc.setProperty('SelectionNamespaces', 'xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');
Dont forget to load the xsd file or schema to the xmldoc object
is the way to go
I dont have enough reputation to comment. But that bit there saved me a lot of time.
Thank you so much
If you are using XMLSerializer and see this error, it is likely that you are running into the IE bug described here:
https://stackoverflow.com/a/11399681
It took me a lot of time to realize that this was happening, so I thought it best to link these two issues.
I mean without input XML file.
I'm using Saxon-EE 9.2.
if you mean to validate the Xquery source file then, the only route I know of is to first convert it to XqueryX using xq2xqx.xsl and then use a xsd schema based on that
An XQuery source file isn't an XML document, so can't be validated with an XML schema. If you really need to, you can use the xq2xqx library to convert XQuery source files into XQueryX documents:
http://monet.nag.co.uk/xq2xml/
The code there needs some tidying up, the XQuery parser linked at
http://www.w3.org/2005/qt-applets/xgrammar.zip
and the Saxon jar - the free one here should work:
http://saxon.sourceforge.net/#F9.4HE
You should end up with a command line something like:
java -cp "saxon9.jar;xquery.jar;trans2.jar" net.sf.saxon.Transform -it:main -o:"xq2xqx.log" -xsl:"xq2xqx.xsl" dump="no$2" xq=test.xquery
which will generate test.xqueryx, and you can then validate the document against the official w3.org schema:
http://www.w3.org/2005/XQueryX/xqueryx.xsd