2

I have the following xml:

<root>    
<rdf:RDF 
   ....
   ....>
  <skos:Concept rdf:about="http://aims.fao.org/skosmos/agrovoc/en/page/c_26321">
    <skos:prefLabel xml:lang="fa">آبیس ماریزی‌ای</skos:prefLabel>
    ....
    <skos:prefLabel xml:lang="en">Abies mariesii</skos:prefLabel>
    <skos:broader rdf:resource="http://aims.fao.org/skosmos/agrovoc/en/page/c_10"/>
  </skos:Concept>

  <skos:Concept rdf:about="http://aims.fao.org/aos/agrovoc/c_5886">
    <skos:prefLabel xml:lang="tr">Pinaceae</skos:prefLabel>
      .... 
    <skos:prefLabel xml:lang="en">Pinaceae</skos:prefLabel>
      ....
    <skos:narrower rdf:resource="http://aims.fao.org/aos/agrovoc/c_10"/>
  </skos:Concept>

Please take note that skos:Concept is a parent node of skos:prefLabel with values Abies mariesii and Pinaceae. Abies mariesii in this case is a broader term () while Pinaceae is a narrower term ()

I have the following xslt:

<xsl:template match="root">
  <xsl:for-each select="rdf:RDF">
  <xsl:text>START HERE</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="skos:Concept" />
  <xsl:text>&#13;&#10;</xsl:text>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="skos:Concept">
   <xsl:if test="skos:broader">
   <xsl:for-each select="skos:prefLabel|skos:Concept" />
   <xsl:text>=301  \\$abroader$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
   <xsl:text>&#13;&#10;</xsl:text>
   </xsl:if>
 </xsl:template>

<xsl:template match="skos:Concept">
  <xsl:if test="skos:narrower">
  <xsl:for-each select="skos:prefLabel|skos:Concept" />
  <xsl:text>=302  \\$anarrower$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
  <xsl:text>&#13;&#10;</xsl:text>
  </xsl:if>
</xsl:template> 
  ....

With this particular template only one is being processed, the latter one. How do I go about this iteration? Of processing both - the broader and the narrower.

Thanks in advance!

schnydszch
  • 435
  • 5
  • 19

3 Answers3

2

It is considered an error to have two templates matching exactly the same node with the same priority. XSLT processors can either flag an error, or ignore all but the last matching template. (See http://www.w3.org/TR/xslt#conflict)

What you need to do is move the xsl:if test out of the body of the template and make it part of the template match itself.

<xsl:template match="skos:Concept[skos:broader]">
   ...
</xsl:template>

<xsl:template match="skos:Concept[skos:narrower]">
   ...
</xsl:template>

Note that this would still fail if an skos:Concept had both a "broader" and "narrower" element present, as then both templates would match the same node again.

Alternatively, simply combine the two templates into one using xsl:choose inside whether different processing is required.

<xsl:template match="skos:Concept">
  <xsl:for-each select="skos:prefLabel|skos:Concept" />
  <xsl:choose>
    <xsl:when test="skos:broader">
       <xsl:text>=301  \\$abroader$b</xsl:text>
    </xsl:when>
    <xsl:when test="skos:narrower">
      <xsl:text>=302  \\$anarrower$b</xsl:text>
    </xsl:when>
  <xsl:value-of select="skos:prefLabel[@xml:lang='en']" />
  <xsl:text>$c</xsl:text>
  <xsl:value-of select="./@rdf:about" />
  <xsl:text>&#13;&#10;</xsl:text>
  </xsl:if>
</xsl:template> 

Switch to using two xsl:if statements if you could have both an "broader" and "narrower" in one skos:Concept

Tim C
  • 70,053
  • 14
  • 74
  • 93
  • Hi Tim C! Thanks for this. I just over-complicated my situation. This is a learning process for me with XSLT. Cheers! – schnydszch Jul 27 '15 at 12:52
0

Change

 <xsl:template match="skos:Concept">
   <xsl:if test="skos:broader">
   <xsl:for-each select="skos:prefLabel|skos:Concept" />
   <xsl:text>=301  \\$abroader$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
   <xsl:text>&#13;&#10;</xsl:text>
   </xsl:if>
 </xsl:template>

<xsl:template match="skos:Concept">
  <xsl:if test="skos:narrower">
  <xsl:for-each select="skos:prefLabel|skos:Concept" />
  <xsl:text>=302  \\$anarrower$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
  <xsl:text>&#13;&#10;</xsl:text>
  </xsl:if>
</xsl:template> 

to

 <xsl:template match="skos:Concept[skos:broader]">
   <xsl:for-each select="skos:prefLabel|skos:Concept" />
   <xsl:text>=301  \\$abroader$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
   <xsl:text>&#13;&#10;</xsl:text>
 </xsl:template>

<xsl:template match="skos:Concept[skos:narrower]">
  <xsl:for-each select="skos:prefLabel|skos:Concept" />
  <xsl:text>=302  \\$anarrower$b</xsl:text><xsl:value-of select="skos:prefLabel[@xml:lang='en']" /><xsl:text>$c</xsl:text><xsl:value-of select="./@rdf:about" />
  <xsl:text>&#13;&#10;</xsl:text>
</xsl:template> 
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Thanks Martin Honnen! However, Tim C's answer lead me on how to figure it out so I choose his. I'll try your answer and give you feedback. Cheers! – schnydszch Jul 28 '15 at 07:47
  • Tim C is correct that it is an error to have two templates matching exactly the same node with the same priority. What I did is the when part (see my answer). Thanks ya'll! – schnydszch Jul 28 '15 at 08:05
0

Thanks for this. I just over-complicated my situation. This is a learning process for me with XSLT. Cheers! Here's the final one:

<xsl:template match="skos:Concept">
 <xsl:for-each select="skos:prefLabel|skos:Concept" />
  <xsl:choose>
   <xsl:when test="skos:broader">
    <xsl:text>=301  \\$abroader$b</xsl:text>
    <xsl:value-of select="skos:prefLabel[@xml:lang='en']" />
    <xsl:text>$c</xsl:text>
    <xsl:value-of select="./@rdf:about" />
    <xsl:text>&#13;&#10;</xsl:text>
   </xsl:when>
    <xsl:when test="skos:narrower">
    <xsl:text>=302  \\$anarrower$b</xsl:text>
    <xsl:value-of select="skos:prefLabel[@xml:lang='en']" />
    <xsl:text>$c</xsl:text>
    <xsl:value-of select="./@rdf:about" />
    <xsl:text>&#13;&#10;</xsl:text>
   </xsl:when>
  </xsl:choose>
 </xsl:template> 
schnydszch
  • 435
  • 5
  • 19