I am trying to do a simple doc insert with the code snippet provided by marklogic.
xdmp:document-insert("/test/shipment1.xml", <shiporder orderid="889923">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city value="BangaloreHighway">>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<var>Special Edition in the industry</var>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>,
map:map() => map:with("collections", ("PRACTICE"))
);
And this is the error I am getting at the line collection.
[1.0-ml] XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected Gt_, expecting Function30_ or Percent_
Stack Trace
At line 32 column 11:
In xdmp:eval("xquery version "1.0-ml";
declare namespace html = ...", (), <options xmlns="xdmp:eval"><database>14078695328357470008</database><modules>99880860359119...</options>)
30. </shiporder>,
31.
32. map:map() => map:with("collections", ("PRACTICE"))
33. );
34
.
MarkLogic extension syntax used, XQuery 3.1 apply to (=>) operators are not supported in 1.0-ml mode (these will work fine MarkLogic 9 onwards); I believe you are using MarkLogic 8 or older.
Try using:
xdmp:document-insert
(
"/test/shipment1.xml"
,
<shiporder orderid="889923">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city value="BangaloreHighway">>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<var>Special Edition in the industry</var>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
,
xdmp:default-permissions()
,
"PRACTICE"
);
Also, I would suggest you to refer the function signatures for the respective MarkLogic version in MarkLogic docs e.g docs.marklogic.com/8.0/xdmp:document-insert.
The "arrow operator" => is available only starting in version X of MarkLogic (I do not have the exact version at hand, I believe it is somewhere between 8 and 9.)
You can use it in any XQuery "version" supported by MarkLogic (3.1 but also 1.0-ml). The following two expressions, with and without the arrow operator, produce the exact same result:
(: if you use 3.1 instead, you need to declare the namespace prefix "map" :)
xquery version "1.0-ml";
map:new((
map:entry('foo', 1),
map:entry('bar', 2)))
,
map:map()
=> map:with('foo', 1)
=> map:with('bar', 2)
If you have only one entry, you can even get rid of the map:new in the first notation:
map:entry('foo', 1)
,
map:map()
=> map:with('foo', 1)
As mentioned by others, in your particular example, you can simply pass different parameters. But now you know about the arrow operator.
Related
Whilst i am using Saxon java api to execute the following xQuery, i am unable to understand why the following execution / validation fails ? (Interestingly , when i replace and clause with or in the if statement, the query validation is successful but am unable to understand this behaviour )
In oxygen xml validator, when i open the xQuery, i get NullPointerException-null exception and the validation fails.
And in java , i get the following area
java.lang.NullPointerException
at net.sf.saxon.expr.parser.LoopLifter.markDependencies(LoopLifter.java:168)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:112)
I am looking up for some experts to help me understand why the following fails.
Following is the xQuery,
declare function local:method($input as element(input)) as element(output)
{
<output>
<itemADetails>
<service>
{
for $i in 1 to count($input/*:foo)
return
for $j in 1 to count($input/*:bar)
return
if((data($input/*:foo[$i]/*:itemB[1]/*:rangeQualifier)="A") and (data($input/*:foo[$i]/*:serviceId/*:type)="B") ) then
<node></node>
else()
}
</service>
</itemADetails>
</output>
};
declare variable $input as element(input) external;
local:method($input)
Saxon Verion
implementation 'net.sf.saxon:Saxon-HE:10.2'
implementation 'net.sf.saxon:saxon-xqj:9.1.0.8'
Sample Snippet that i tried
Processor saxon = new Processor(false);
// compile the query
XQueryCompiler compiler = saxon.newXQueryCompiler();
XQueryExecutable exec;
ClassLoader classLoader = MessageProcessor.class.getClassLoader();
exec = compiler.compile(new File(classLoader.getResource("Xquery.xqy").getFile()));
Source src = new StreamSource(new StringReader(Files.readString( Paths.get(ClassLoader.getSystemResource(inputfile.xml").toURI()))));
XdmNode doc = builder.build(src);
// instantiate the query, bind the input and evaluate
XQueryEvaluator query = exec.load();
query.setContextItem(doc);
query.setExternalVariable(new QName("input"), doc.select(child("input")).asNode());
XdmValue result = query.evaluate();
System.out.println(result.itemAt(0).toString());
Irrespective of the java code when i open the xquery in Oxygen XML editor (that uses Saxon-PE XQuery 9.9.1.7 engine) , i get the following validation error.
It is indeed a Saxon optimisation bug. The problem occurs when Saxon attempts to rewrite
for $j in 1 to count($input/bar)
return if ($input/foo[$i]/data = 'A' and $input/baz[$i]/type = 'B')
then <result/>
else ()
as
if ($input/foo[$i]/data = 'A' and $input/baz[$i]/type = 'B')
then for $j in 1 to count($input/bar)
return <result/>
else ()
and you can work around the problem by doing this rewrite "by hand". The purpose of the rewrite is to prevent the unnecessary repeated evaluation of the "if" condition, which is the same each time round the loop.
The reason it's dependent on the "and" condition is that Saxon considers each term of the "and" as a separate candidate for promoting outside the loop, and when it finds that all these terms can be promoted, it reconstitutes the "and" expression from its parts, and the bug occurs during this reconstitution.
It seems like an optimizer bug in Saxon, I reduced your code to
declare function local:test($input as element(input)) as element(output)
{
<output>
<details>
<service>
{
for $i in 1 to count($input/foo)
return
for $j in 1 to count($input/bar)
return if ($input/foo[$i]/data = 'A' and $input/baz[$i]/type = 'B')
then <result/>
else ()
}
</service>
</details>
</output>
};
declare variable $input as element(input) external := <input>
</input>;
local:test($input)
and Saxon HE 10.2 from the command line crashes with
java.lang.NullPointerException
at net.sf.saxon.expr.parser.LoopLifter.markDependencies(LoopLifter.java:168)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:112)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:122)
at net.sf.saxon.expr.parser.LoopLifter.gatherInfo(LoopLifter.java:101)
at net.sf.saxon.expr.parser.LoopLifter.process(LoopLifter.java:51)
at net.sf.saxon.query.XQueryFunction.optimize(XQueryFunction.java:452)
at net.sf.saxon.query.XQueryFunctionLibrary.optimizeGlobalFunctions(XQueryFunctionLibrary.java:327)
at net.sf.saxon.query.QueryModule.optimizeGlobalFunctions(QueryModule.java:1207)
at net.sf.saxon.expr.instruct.Executable.fixupQueryModules(Executable.java:458)
at net.sf.saxon.query.XQueryParser.makeXQueryExpression(XQueryParser.java:177)
at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:568)
at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:630)
at net.sf.saxon.s9api.XQueryCompiler.compile(XQueryCompiler.java:609)
at net.sf.saxon.Query.compileQuery(Query.java:804)
at net.sf.saxon.Query.doQuery(Query.java:317)
at net.sf.saxon.Query.main(Query.java:97)
java.lang.NullPointerException
I think on the command line you can turn off optimization with -opt:0, then the above code doesn't crash.
You might want to raise your bug as an issue on https://saxonica.plan.io/projects/saxon/issues or wait until someone from Saxonica picks it up here.
If I use
for $foo at $i in $input/foo
return
for $bar at $j in $input/bar
Saxon doesn't crash, so perhaps that is a way to rewrite your query as a workaround, although, without data, I am not quite sure I have captured the meaning of your code and that rewrite does the same as your original attempt.
I reproduced it with Martin's test case (thank you, Martin): https://saxonica.plan.io/issues/4765
I am using schematron API in MarkLogic to validate the XML document. Below is the snippet of code for reference.
xquery version "1.0-ml";
import module namespace sch = "http://marklogic.com/validate" at
"/MarkLogic/appservices/utils/validate.xqy";
import module namespace transform = "http://marklogic.com/transform" at "/MarkLogic/appservices/utils/transform.xqy";
declare namespace xsl = "http://www.w3.org/1999/XSL/not-Transform";
declare namespace iso = "http://purl.oclc.org/dsdl/schematron";
let $document :=
document{
<book xmlns="http://docbook.org/ns/docbook">
<title>Some Title</title>
<chapter>
<para>...</para>
</chapter>
</book>
}
let $schema :=
<s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
xmlns:db="http://docbook.org/ns/docbook">
<s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
<s:pattern name="Glossary 'firstterm' type constraint">
<s:rule context="db:chapter">
<s:assert test="db:title">Chapter should contain title</s:assert>
</s:rule>
</s:pattern>
</s:schema>
return
sch:schematron($document, $schema)
Can anyone help me out to get the XPath information of the context node along with schematron error message output.
Here is code for what I think you are asking for.
If you want the xpath of an item you can use xdmp:path. in order to get the xpath of the whole document you'll just have to walk the tree, which is what the recursive function local:getXpathDeep is doing. You can change the formatting of the output from the string-join that I used, it just made it easier to read for me. I created an XML output to put both the schematron results and the XPath into but you can just return a sequence if you like or put it into a map.
xquery version "1.0-ml";
import module namespace sch = "http://marklogic.com/validate" at
"/MarkLogic/appservices/utils/validate.xqy";
import module namespace transform = "http://marklogic.com/transform" at "/MarkLogic/appservices/utils/transform.xqy";
declare namespace xsl = "http://www.w3.org/1999/XSL/not-Transform";
declare namespace iso = "http://purl.oclc.org/dsdl/schematron";
declare function local:getXpathDeep($node){
(
xdmp:path($node),
if (fn:exists($node/*)) then (
local:getXpathDeep($node/*)
) else ()
)
};
let $document :=
document{
<book xmlns="http://docbook.org/ns/docbook">
<title>Some Title</title>
<chapter>
<para>...</para>
</chapter>
</book>
}
let $schema :=
<s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
xmlns:db="http://docbook.org/ns/docbook">
<s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
<s:pattern name="Glossary 'firstterm' type constraint">
<s:rule context="db:chapter">
<s:assert test="db:title">Chapter should contain title</s:assert>
</s:rule>
</s:pattern>
</s:schema>
return
<result>
<contextNodeXpath>{fn:string-join(local:getXpathDeep($document), "
" )}</contextNodeXpath>
<schematronOutPut>{sch:schematron($document, $schema)}</schematronOutPut>
</result>
That particular Schematron module is rather limited and does not provide a way to return the XPath for the context node from a report or failed assert.
The standard Schematron SVRL output does include the XPath for the items that fire failed asserts or reports.
Norm Walsh has published the ML-Schematron module that wraps the compilation of a Schematron schema into an XSLT using the Schematron stylesheets, and subsequent execution of the compiled XSLT to generate the SVRL report.
You could adjust your module to use it instead (after installing it and the standard Schematron XSLT files in your Modules database):
xquery version "1.0-ml";
declare namespace svrl="http://purl.oclc.org/dsdl/svrl";
import module namespace sch="http://marklogic.com/schematron" at "/schematron.xqy";
let $document :=
document{
<book xmlns="http://docbook.org/ns/docbook">
<title>Some Title</title>
<chapter>
<para>...</para>
</chapter>
</book>
}
let $schema :=
<s:schema xmlns:s="http://purl.oclc.org/dsdl/schematron"
xmlns:db="http://docbook.org/ns/docbook">
<s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>
<s:pattern name="Glossary 'firstterm' type constraint">
<s:rule context="db:chapter">
<s:assert test="db:title">Chapter should contain title</s:assert>
</s:rule>
</s:pattern>
</s:schema>
return
sch:validate-document($document, $schema)
It produces the following SVRL report, which includes the XPath in the location attribute /*[local-name()='book']/*[local-name()='chapter']:
<svrl:schematron-output title="" schemaVersion="" xmlns:schold="http://www.ascc.net/xml/schematron"
xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:db="http://docbook.org/ns/docbook" xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:svrl="http://purl.oclc.org/dsdl/svrl">
<!---->
<svrl:ns-prefix-in-attribute-values uri="http://docbook.org/ns/docbook" prefix="db"/>
<svrl:active-pattern document=""/>
<svrl:fired-rule context="db:chapter"/>
<svrl:failed-assert test="db:title" location="/*[local-name()='book']/*[local-name()='chapter']">
<svrl:text>Chapter should contain title</svrl:text>
</svrl:failed-assert>
</svrl:schematron-output>
Mule ESB DataMapper: Aggregation of field conditional to field type
I have the following structures:
Strcuture A:
<itemlist>
<item>
<id>123</id>
<price>1</price>
<quantity>1</quantity>
<type>AAA</type>
</item>
<item>
<id>124</id>
<price>2</price>
<quantity>1</quantity>
<type>BBB</type>
</item>
<item>
<id>125</id>
<price>3</price>
<quantity>1</quantity>
<type>BBB</type>
</item>
<itemlist>
Structure B:
<totals>
<total>
<totalPrice>3</totalPrice>
</total>
</totals>
If I want a sumation of all the field, but only
for structures with a of "BBB".
Can I do this in Mule ESB, and if so how would I do it?
Thanks
Use a rule, like described in a your previous question, but use the following xpath: sum(//price[../type='BBB']).
I have a xml document same as:
<otx xmlns="http://iso.org/OTX/1.0.0" xmlns:i18n="http://iso.org/OTX/1.0.0/i18n" xmlns:diag="http://iso.org/OTX/1.0.0/DiagCom" xmlns:measure="http://iso.org/OTX/1.0.0/Measure" xmlns:string="http://iso.org/OTX/1.0.0/StringUtil" xmlns:dmd="http://iso.org/OTX/1.0.0/Auxiliaries/DiagMetaData" xmlns:fileXml="http://vwag.de/OTX/1.0.0/XmlFile" xmlns:log="http://iso.org/OTX/1.0.0/Logging" xmlns:file="http://vwag.de/OTX/1.0.0/File" xmlns:dataPlus="http://iso.org/OTX/1.0.0/DiagDataBrowsingPlus" xmlns:event="http://iso.org/OTX/1.0.0/Event" xmlns:quant="http://iso.org/OTX/1.0.0/Quantities" xmlns:hmi="http://iso.org/OTX/1.0.0/HMI" xmlns:math="http://iso.org/OTX/1.0.0/Math" xmlns:flash="http://iso.org/OTX/1.0.0/Flash" xmlns:data="http://iso.org/OTX/1.0.0/DiagDataBrowsing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dt="http://iso.org/OTX/1.0.0/DateTime" xmlns:eventPlus="http://iso.org/OTX/1.0.0/EventPlus" xmlns:corePlus="http://iso.org/OTX/1.0.0/CorePlus" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:job="http://iso.org/OTX/1.0.0/Job" id="id_4e5722f2f81a4309860c146fd3c743e5" name="NewDocument1" package="NewOtxProject1Package1" version="1.0.0.0" timestamp="2014-04-11T09:42:50.2091628+07:00">
<declarations>
<constant id="id_fdc639e20fbb42a4b6b039f4262a0001" name="GlobalConstant">
<realisation>
<dataType xsi:type="Boolean">
<init value="false"/>
</dataType>
</realisation>
</constant>
</declarations>
<metaData>
<data key="MadeWith">Created by emotive Open Test Framework - www.emotive.de</data>
<data key="OtfVersion">4.1.0.8044</data>
</metaData>
<procedures>
<procedure id="id_1a80900324c64ee883d9c12e08c8c460" name="main" visibility="PUBLIC">
<realisation>
<flow/>
</realisation>
</procedure>
</procedures>
</otx>
I want to remove unsused namespaces in the xml by xquery but i don't know any solution to solving it. the current namespace used are "http://iso.org/OTX/1.0.0 and http://www.w3.org/2001/XMLSchema-instance".
please help me!.
Unfortunately, XQuery Update provides no expression to remove existing namespaces, but you can recursively rebuild your document:
declare function local:strip-ns($n as node()) as node() {
if($n instance of element()) then (
element { node-name($n) } {
$n/#*,
$n/node()/local:strip-ns(.)
}
) else if($n instance of document-node()) then (
document { local:strip-ns($n/node()) }
) else (
$n
)
};
let $xml :=
<A xmlns="used1" xmlns:unused="unused">
<b:B xmlns:b="used2"/>
</A>
return local:strip-ns($xml)
I am executing selenium script on iPhone simulator , i am running server via ios-server0.6.3.jar . i am able to get all xslt reports on Mac by running scripts on safari browser, but when i am trying to execute the same script on iPhone simulator, getting following xslt exception..
[xslt] Processing /test-output/testng-results.xml to /XSLT_Reports/output/index.html
[xslt] Loading stylesheet /src/xslt/testng-results.xsl
[xslt] /src/xslt/testng-results.xsl:461:93:
Fatal Error! Cannot find a matching 1-argument function named {http://exslt.org/math}cos().
There is no Saxon extension function with the local name cos
[xslt] /src/xslt/testng-results.xsl:462:98: Fatal Error! Cannot find a matching 1-argument function named {http://exslt.org/math}sin(). There is no Saxon extension function with the local name sin
[xslt] /src/xslt/testng-results.xsl:466:111: Fatal Error! Cannot find a matching 1-argument function named {http://exslt.org/math}cos(). There is no Saxon extension function with the local name cos
[xslt] /src/xslt/testng-results.xsl:467:118: Fatal Error! Cannot find a matching 1-argument function named {http://exslt.org/math}sin(). There is no Saxon extension function with the local name sin
Following code may creating problem:
<xsl:variable name="pi" select="3.141592"/>
<xsl:variable name="radius" select="130"/>
<xsl:variable name="failedPercent" select="format-number($failedCount div $totalCount, '###%')"/>
<xsl:variable name="failedAngle" select="($failedCount div $totalCount) * $pi * 2"/>
<xsl:variable name="failedX" select="$radius * math:cos($failedAngle)"/>
<xsl:variable name="failedY" select="-1 * $radius * math:sin($failedAngle)"/>
<xsl:variable name="failedArc" select="if ($failedAngle >= $pi) then 1 else 0"/>
<xsl:variable name="failedAngle_text" select="$failedAngle div 2"/>
<xsl:variable name="failedX_text" select="($radius div 2) * math:cos($failedAngle_text)"/>
<xsl:variable name="failedY_text" select="(-1 * ($radius div 2) * math:sin($failedAngle_text))"/>
Finally i solved my problem. Actually ios-server.jar was creating problem while generating xslt reports. So after execution of scripts, i removed ios-driver.jar file from build path and then run command for generating xslt report.