0

I am trying to compare new xml file with existing xml inside the basex database('db') but it checks only the existence of the file within 'db' and it is returning true whether contents are same or not.

I also want to check contents of xml file which i am passing with matching xml file inside the database('db').So that if contents are same then it should be return 'true' otherwise false.

Please any one can help me to provide the best way.

 String query = "for $doc in collection('db') return if(matches(document-uri($doc),'"+xmlFile+"')) then  true() else false()";
manish payasi
  • 77
  • 1
  • 10

2 Answers2

0

Use fn:deep-equal(). It compares two sequences and checks whether they have the same values and in the same order.

for $doc in collection('db') return deep-equal($doc, doc('"+xmlFile+"'))

Also, it is not very elegant to pass in the variable as you do here. It is much better to declare the variable as external in your XQuery and bind it in your Java code. It will look something like that:

Context context = new Context();
String query = "declare variable $xml-file as xs:string external;" +
               "for $doc in collection('db') return deep-equal($doc, doc($xml-file))";
QueryProcessor proc = new QueryProcessor(query, context);
proc.bind("xml-file", xmlFile);
Result result = proc.execute(); // your result
proc.close();
context.close();
dirkk
  • 6,160
  • 5
  • 33
  • 51
  • 1
    It's not only "inelegant", it's also insecure. You lay yourself open to code injection attacks. – Michael Kay Jul 17 '14 at 09:13
  • @MichaelKay I completely agree. However, I haven't seen any XQuery injection attacks so far, due to the functional nature of XQuery it seems non-trivial to me (although certainly it is possible). However, I would love to see some practical XQuery code injection attacks. – dirkk Jul 17 '14 at 09:39
  • When the W3C first mounted a "run your own XSLT code" web site, I quickly established that it used the XT processor, that calls out to Java were not disabled, and that it was possible to explore the full directory structure of the server and display or modify the contents of any file. XQuery injection could do exactly the same if you don't take care. – Michael Kay Jul 17 '14 at 19:41
  • Hi dirkk, Suppose i have created xml without storing any directory,how to compare this xml file with existing xml files inside database. B/c in above example i am creating xml and that is storing in some directory then i get the file from directory and compare with xml file inside database but now i do'nt want to store in any directory. So i just want to create xml file dynamically and compare it. – manish payasi Jul 18 '14 at 13:30
  • @manishpayasi I really don't get what you are trying to do. What is a _directory_? Do you mean a database or maybe a path? I am unsure. However, it is probably best to simply ask a new question as it seems to be quite different from this question. – dirkk Jul 18 '14 at 13:34
  • Hi dirkk, Thank you for your assistant. Actually directory is a file system(like C ,D drive or any path in my system).So my question was I want to create a new xml file but it shouldn't be store in any path in my system and then i want to compare this new xml file contents with existing xml file contents inside the database('db'). And I also don't want to use doc() function because it fetches the record from my file system(path). Thanks once again...... – manish payasi Jul 21 '14 at 04:25
  • Use `parse-xml(file:read-text($your-file))` to read and parse an XML file from disk. – dirkk Jul 21 '14 at 07:07
  • String query = "declare variable $xml-file as xs:string external;" "for $doc in collection('db')where matches(document-uri($doc), '" + xmlFile + "') return deep-equal($doc, $xml-file)"; QueryProcessor proc = new QueryProcessor(query, context); proc.bind("xml-file", xmlFile); Result result = proc.execute(); // your result System.out.println(result); – manish payasi Jul 21 '14 at 10:02
  • Hi drikk, see the above code snapshot,through which might be you can understand what i want. Instead of deep-equal($doc, doc('"+xmlFile+"') i am trying to use deep-equal($doc,"+xmlFile+"). So is it possible? – manish payasi Jul 21 '14 at 11:26
  • I am not going to read horribly formatted code in comments. The comment section is **not** the right place for extended discussion. As I said before, please ask a new question with all the information in one place and nicely formatted code. – dirkk Jul 21 '14 at 12:16
0
  • You need to retrieve the collection of documents.
  • matches is for comparing strings against regular expressions, not XML contents. Use deep-equal instead.

Replace the database / file names as needed:

let $new-document := doc('factbook.xml')
return
  some $document in collection('factbook')
  satisfies deep-equal($document, $new-document)

This will return true, if the new document equals any of the already available documents.

Jens Erat
  • 37,523
  • 16
  • 80
  • 96