Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xmlquery to remove data from xml file that is in another xml file?

Status
Not open for further replies.

zapster

Programmer
Jun 8, 2001
36
GB
Hi All,

I'm new to xmlquery and I trying to combine to xml files so that I can produce a third file which contains a smaller dataset ie fileA.xml - fileB.xml = fileC.xml

I have the following XML Schemas

could any on help me ?

Code:
FileA.xml

<Products>
  <Product>
    <brand></brand>
    <catalogueNumber>AA05715</catalogueNumber>
    <category>Women | Brands | Dresses &amp; Skirts</category>
    <colour></colour>
    <colours></colours>
    <gender></gender>
    <image></image>
    <keyword></keyword>
    <keywords></keywords>
    <longDescription>Contrast trims and distressing detail. Length 14ins. Cotton. Machine washable. Light-wash.</longDescription>
    <modelNumber></modelNumber>
    ....
    ....
    .....
  </Product>
  <Product>
    ....
  </Product>
</Products>


FileB.xml

<Exclude>
  <catalogueNumber>AA01111</catalogueNumber>
  <catalogueNumber>AA05715</catalogueNumber>
  <catalogueNumber>AA22222</catalogueNumber>
  ....
  ....
</Exclude>

The query need to remove all the product nodes that contain a matching catalogueNumber in the second file? and output the result in a third file.

Hope you can help me with the query

Thanks
Zapster
 
For this kind of task, you can think along this way.
[1] Device an identity transformation preversing everything. (You can use an import or just put it all there as it is a short template.)
[2] Device a collection of specific templates overriding the identity transformation and doing the exclusion work.

Like this.
[tt]
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:param name="exclude" select="document('[green]FileB.xml[/green]')/Exclude/catalogueNumber" />

<!-- either import an identity transformation or put it here -->
<xsl:template match="/">
<xsl:apply-templates select="*" />
</xsl:template>

<xsl:template match="node()|@*|comment()|processing-instruction()|text()">
<xsl:copy>
<xsl:apply-templates select="node()|@*|comment()|processing-instruction()|text()" />
</xsl:copy>
</xsl:template>

<!-- specific templates here -->

<xsl:template match="Product">
<xsl:choose>
<xsl:when test="count($exclude[text() = current()/catalogueNumber/text()]) != 0" />
<xsl:eek:therwise>
<xsl:copy>
<xsl:apply-templates select="node()|@*|comment()|processing-instruction()|text()" />
</xsl:copy>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>
[/tt]
 
Thanks Tsuji,

but I was hopping to do it in xquery. From my sql knowledge I thought there would be a way of replicating a similar xquery as this sql
Code:
select * from fileA
where fileA.catalogueNumber not in (select fileB.catalogueNumber from fileB)
does anybody know if there is a way to do this in xquery, if so what is the syntax

Thanks Once again
Zapster
 
Try this.
[tt]
document {
<Products> {
let $exclude := doc("zp25a_exclude.xml")
let $source := doc("zp25a_test.xml")
for $i in $source/Products//Product
let $nodes := $exclude/Exclude/catalogueNumber[text() = $i/catalogueNumber/text()]
where count($nodes) = 0
return $i
}
</Products>
}[/tt]
 
Further note:

I used specific testing file names for your FileA.xml and FileB.xml. I intended to use notation you're familiar. This is a relist.
[tt]
document {
<Products> {
let $exclude := doc("FileB.xml")
let $source := doc("FileA.xml")
for $i in $source/Products//Product
let $nodes := $exclude/Exclude/catalogueNumber[text() = $i/catalogueNumber/text()]
where count($nodes) = 0
return $i
}
</Products>
}
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top