Good afternoon,
I have a QueryProcessor to grab the top level items which works, but then I want to iterate over these items to query sub-items. My XML is currently (sub-section, excuse any typos however it is well formed)
<MappingRequest> <Mappings destination="invoice_sftp" map="pdf_invoice"> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/invoice/2/3/1/231749.pdf" xpath="//CommercialDocument[@id='231749']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/invoice/2/3/1/231750.pdf" xpath="//CommercialDocument[@id='231750']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/invoice/2/3/1/231751.pdf" xpath="//CommercialDocument[@id='231751']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/invoice/2/3/1/231752.pdf" xpath="//CommercialDocument[@id='231752']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/invoice/2/3/1/231753.pdf" xpath="//CommercialDocument[@id='231753']"/> </Mappings> <Mappings destination="invoice_sftp" map="pdf_device_report"> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/report/8/3/7/8375680.pdf" xpath="//Device[@report_id='8375680']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/report/8/3/7/8375681.pdf" xpath="//Device[@report_id='8375681']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/report/8/3/7/8375679.pdf" xpath="//Device[@report_id='8375679']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/report/8/3/7/8375682.pdf" xpath="//Device[@report_id='8375682']"/> <Mapping path="/var/lib/michrosatbilling/billingrunoutput_testing/dummy/report/8/3/7/8375686.pdf" xpath="//Device[@report_id='8375686']"/> </Mappings> </MappingRequest>
My code in brief is:
final Context context = new Context(); new CreateDB("LocalDB", "/test.xml").execute(context); QueryProcessor proc = new QueryProcessor("/MappingRequest/Mappings", context);
// Loop over the mappings, get the map name then iterate over the underlying mapping nodes for(Item item; (item = iter.next()) != null;) { Object elem = BXNode.get((ANode)item); BXElem node1 = (BXElem)elem; System.out.println(node1.getAttribute("map"));
QueryProcessor proc2 = proc.context(item); proc2.??("/Mapping"); Iter iter2 = proc.iter();
for(Item item2; (item2 = iter2.next()) != null;) { elem = BXNode.get((ANode)item2); node1 = (BXElem)elem; System.out.println(node1.getNodeName()); } }
Having worked with Saxon previously I was able to pass the XdmItem from one query to the context of another query - allowing further queries to be carried out, therefore I assumed I would be able to something similar with BaseX? Feel I'm almost there with various ideas but nothing seems to change the context to the an item, rather than sticking with the originally loaded document.
Secondly to this I need to workout how to perform the queries via a ClientSession - however that only seems to return a ClientQuery where .next() returns a String, rather than a workable Item or other object.
Kind regards
Chris Speare
The information contained in the email and any files transmitted with it is confidential and intended for the addressee only. If you have received this email in error please accept our apologies and notify the originator. Any disclosure, copying, distribution or any other use of this communication is strictly prohibited and may be unlawful. We reserve the right to monitor and intercept communications for lawful business purposes.
Wireless Innovation Ltd , Unit D2, Churcham Business Park, Churcham, Gloucestershire, GL2 8AX, Great Britain.
Company Registration Number 5240202, Place of Registration Companies House Cardiff.
Hi Chris,
Having worked with Saxon previously I was able to pass the XdmItem from one query to the context of another query - allowing further queries to be carried out, therefore I assumed I would be able to something similar with BaseX?
Here are two ways to do so:
QueryProcessor proc1 = new QueryProcessor("/MappingRequest/Mappings", context); Iter iter1 = proc1.iter(); for(Item item1; (item1 = iter1.next()) != null;) { QueryProcessor proc2 = new QueryProcessor("Mapping", context); proc2.context(item1); Iter iter2 = proc2.iter(); for(Item item2; (item2 = iter2.next()) != null;) { System.out.println(((ANode) item2).qname()); } }
More compact (but may be less efficient if you do not want to process all results):
QueryProcessor proc1 = new QueryProcessor("/MappingRequest/Mappings", context); for(Item item1 : proc1.value()) { for(Item item2 : new QueryProcessor("Mapping", context).context(item1).value()) { System.out.println(item2.serialize()); } }
Secondly to this I need to workout how to perform the queries via a ClientSession - however that only seems to return a ClientQuery where .next() returns a String, rather than a workable Item or other object.
True; the solution above does not work with the client/server architecture. In that case, you’ll need to resort to XQJ or – which is what we usually do – do as much as possible in XQuery itself
Cheers, Christian
Christian,
That works wonderfully and after looking back and forth between what I had and what you provided have spotted my error:
Iter iter2 = proc.iter();
Iterator referring to the wrong processor. I'll have a look at XQJ as you suggested as I want as much processing on the server side to avoid saving the document locally to query against.
Many thanks
Chris Speare
On 23/12/15 10:04, Christian Grün wrote: Hi Chris,
Having worked with Saxon previously I was able to pass the XdmItem from one query to the context of another query - allowing further queries to be carried out, therefore I assumed I would be able to something similar with BaseX?
Here are two ways to do so:
QueryProcessor proc1 = new QueryProcessor("/MappingRequest/Mappings", context); Iter iter1 = proc1.iter(); for(Item item1; (item1 = iter1.next()) != null;) { QueryProcessor proc2 = new QueryProcessor("Mapping", context); proc2.context(item1); Iter iter2 = proc2.iter(); for(Item item2; (item2 = iter2.next()) != null;) { System.out.println(((ANode) item2).qname()); } }
More compact (but may be less efficient if you do not want to process all results):
QueryProcessor proc1 = new QueryProcessor("/MappingRequest/Mappings", context); for(Item item1 : proc1.value()) { for(Item item2 : new QueryProcessor("Mapping", context).context(item1).value()) { System.out.println(item2.serialize()); } }
Secondly to this I need to workout how to perform the queries via a ClientSession - however that only seems to return a ClientQuery where .next() returns a String, rather than a workable Item or other object.
True; the solution above does not work with the client/server architecture. In that case, you’ll need to resort to XQJ or – which is what we usually do – do as much as possible in XQuery itself
Cheers, Christian
The information contained in the email and any files transmitted with it is confidential and intended for the addressee only. If you have received this email in error please accept our apologies and notify the originator. Any disclosure, copying, distribution or any other use of this communication is strictly prohibited and may be unlawful. We reserve the right to monitor and intercept communications for lawful business purposes.
Wireless Innovation Ltd , Unit D2, Churcham Business Park, Churcham, Gloucestershire, GL2 8AX, Great Britain.
Company Registration Number 5240202, Place of Registration Companies House Cardiff.
basex-talk@mailman.uni-konstanz.de