Below are two XML files. I want to filter XMLA to only those people who exist in XMLB, using the name
field.
Both the XML documents are stored in the variables $XMLA and $XMLB.
I created the output using XQuery 1.0 but I am not sure how to perform the same operation in XSLT 1.0.
XMLA:
<table>
<row>
<name>NNN</name>
<address>1234 NN</address>
<phone>23423423</phone>
</row>
<row>
<name>kkk</name>
<address>1234 KK</address>
<phone>4343434</phone>
</row>
</table>
XMLB:
<table>
<row>
<id>1111</id>
<batch>1212</batch>
<name>NNN</name>
</row>
<row>
<id>2222</id>
<batch>2121</batch>
<name>kkk</name>
</row>
</table>
XQuery:
for $y in fn:doc('XMLA.xml')/table/row
for $x in fn:doc('XMLB.xml')/table/row
for $a in $x/name
where $y/name = $a
order by $y/name
return $y
The reason I am looking into XSLT is because the parsing on large XML file is extremely slow with XQuery. I am not sure if that is because of my XQuery built wrong, but I want to give XSLT a try and compare the efficiency.
It looks like your XQuery approach allocates a brand-new document B for every <row>
in document A.
Use variables to store the documents once.
xquery version "1.0";
(: your call to fn:doc('XMLA.xml') here :)
let $A := <table>
<row>
<name>NNN</name>
</row>
<row>
<name>kkk</name>
</row>
<row>
<name>xxx</name>
</row>
</table>
(: your call to fn:doc('XMLB.xml') here :)
let $B := <table>
<row>
<name>nnnn</name>
</row>
<row>
<name>kkk</name>
</row>
<row>
<name>xxx</name>
</row>
</table>
let $nameA := $A/row/name
let $nameB := $B/row/name
for $name in $nameA
where $name = $nameB
order by $name
return $name
returns
<name>kkk</name>
<name>xxx</name>
for me. Check if performance improves.