2

I have a collection of plays and poems from different authors. My XML looks like this:

<works>
    <editions>
       <edition>
           <playtitle>Henry IV, Part 1</playtitle>
           <playcode>1H4</playcode>
           <genre>play</genre>
           <metadataBlock>
               <meta content="Shakespeare, William" name="Creator"/>
           </metadataBlock>
       </edition>
    </editions>
</works>

I have used the following code successfully to extract the "playcode" from all the plays:

<xsl:when test="$only = 'plays'">
    <xsl:sequence select="/works/editions/edition[genre = 'play']/playcode"/>
</xsl:when>

However, I cannot figure it out how to extract the "playcode" from all the plays written by Shakespeare. I have tried multiple possibilities such as:

<xsl:when test="$only = 'plays'">
    <xsl:sequence select="/works/editions/edition[genre = 'play' 
        and @content='Shakespeare, William' 
        and @name='Creator']/playcode"/>
</xsl:when>

And such as:

<xsl:when test="$only = 'plays'">
      <xsl:sequence select="/works/editions/edition[genre =       
        'play']/playcode/metadataBlock/meta[@content='Shakespeare, William' 
           and@name='Creator']"/>
</xsl:when>

What am I missing??

mfroese
  • 309
  • 1
  • 5
  • 18

2 Answers2

1

In your first suggestion you try to evaluate content and name attributes of edition elements. Since they don't exist, the resulting sequence is empty. Thus, modify the XPath expression like this for example:

<xsl:when test="$only = 'plays'">
  <xsl:sequence select="/works/editions/edition[
    genre='play' and
    metadataBlock/meta[
      @content='Shakespeare, William' and
      @name='Creator'
    ]
  ]/playcode"/>
</xsl:when>
Martin
  • 1,748
  • 1
  • 16
  • 15
0

I would use keys -- both for convenience and efficiency:

key('kPlaysByAuthor', 'Shakespeare, William')

To select just the playcode:

key('kPlaysByAuthor', 'Shakespeare, William')/playcode

Here is a complete example:

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:key name="kPlaysByAuthor" match="edition"
      use="metadataBlock/meta[@name='Creator']/@content"/>

     <xsl:template match="/">
         <xsl:copy-of select=
          "key('kPlaysByAuthor', 'Shakespeare, William')/playcode"/>
     </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<works>
    <editions>
       <edition>
           <playtitle>Henry IV, Part 1</playtitle>
           <playcode>1H4</playcode>
           <genre>play</genre>
           <metadataBlock>
               <meta content="Shakespeare, William" name="Creator"/>
           </metadataBlock>
       </edition>
       <edition>
           <playtitle>Some Title</playtitle>
           <playcode>XYZ</playcode>
           <genre>play</genre>
           <metadataBlock>
               <meta content="Someone, Else" name="Creator"/>
           </metadataBlock>
       </edition>
    </editions>
</works>

the wanted, correct result is produced:

<playcode>1H4</playcode>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431