tags:

views:

89

answers:

1

Here is my input XML:

<Books>
  <Book>
    <BookId>1</BookId>
    <Des>Dumm1</Des>
    <Comments/>
    <OrderDateTime>04/06/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>2</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>04/07/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>3</BookId>
    <Des>Dumm12</Des>
    <Comments/>
    <OrderDateTime>05/06/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>4</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>06/07/2009 12:37</OrderDateTime>
  </Book>
</Books>

I pass an XML param and my Input XML is

<BookIDs>
  <BookID>2</BookID>
  <BookID>3</BookID>
</BookIDs>

My output should be like

<Books>
  <Book>
    <BookId>2</BookId>
    <Des>Dummy2</Des>
    <Comments/>
    <OrderDateTime>04/07/2009 12:37</OrderDateTime>
  </Book>
  <Book>
    <BookId>3</BookId>
    <Des>Dumm12</Des>
    <Comments/>
    <OrderDateTime>05/06/2009 12:37</OrderDateTime>
  </Book>
</Books>

How do I accomplish this using XSLT.

A: 

This works in Saxon 6.5.5...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
    <xsl:param name="nodeset">
     <BookIDs><BookID>2</BookID><BookID>3</BookID></BookIDs>
    </xsl:param>

    <xsl:template match="/Books">
     <Books>
      <xsl:variable name="Copy">
       <wrap>
        <xsl:copy-of select="Book"/>
       </wrap>
      </xsl:variable>
      <xsl:for-each select="$nodeset/BookIDs/BookID">
       <xsl:copy-of select="$Copy/wrap/Book[BookId=current()]"/>
      </xsl:for-each>
     </Books>
    </xsl:template>
</xsl:stylesheet>

A pure XSLT solution will be pretty brittle though. Sub-query predicates didn't work, neither did a key. It is dependent upon the param being recognized as a node-set--which I was unable to achieve with a dynamic value (as opposed to the default in my example), even with exsl:node-set. This is also wasteful in that it copies all the Book elements from the source document.

There may be a better solution in XSLT 2.0. Alternately, if you are initiating your transform with some other language/tool, there may be better approaches available there. Another possibility could include the use of exsl:document to load your source document or params.

steamer25