Search code examples
xmlxsltrdfskos

xsl can not get the value of attribute


This is related to a question i posted here xslt get element value based on attribute which is referenced in another node tree I'm trying out first to get the value of an attribute but I can't seem to get it, here again is the xml:

 <?xml version="1.0" encoding="utf-8" ?>
  <root>
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:skosxl="http://www.w3.org/2008/05/skos-xl#"
   xmlns:skos="http://www.w3.org/2004/02/skos/core#"
   xmlns:dc="http://purl.org/dc/terms/"
   xmlns:ns0="http://art.uniroma2.it/ontologies/vocbench#"
   xmlns:void="http://rdfs.org/ns/void#">

  <skos:Concept rdf:about="http://aims.fao.org/aos/agrovoc/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/aos/agrovoc/c_10"/>
  </skos:Concept>

  <skos:Concept rdf:about="http://aims.fao.org/skosmos/agrovoc/en/page/c_1591">
   <skos:prefLabel xml:lang="ar">أشجار عيد الميلاد</skos:prefLabel>
        ....
   <skos:prefLabel xml:lang="en">christmas trees</skos:prefLabel>
     ....

  </skos:Concept>

     ....

  <skos:Concept>
   <ns0:isUsedAs rdf:resource="http://aims.fao.org/skosmos/agrovoc/en/page/c_7776"/>
   <ns0:isUsedAs rdf:resource="http://aims.fao.org/skosmos/agrovoc/en/page/c_1591"/>
  </skos:Concept>

 </rdf:RDF>    
 </root>

I have the following templates:

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0"
  ....
 xmlns:void="http://rdfs.org/ns/void#">
 <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
 <xsl:template match="root">
  <xsl:for-each select="rdf:RDF">
   <xsl:text>START HERE</xsl:text>
   <xsl:text>&#13;&#10;</xsl:text>
   <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
   <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="rdf:Description/skos:narrowMatch" />
   <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="rdf:Description/skos:exactMatch" />
   <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="skos:Concept" />
   <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="skos:Concept/skos:altLabel" />
   <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="skos:Concept/skos:prefLabel" />
   <xsl:text>&#13;&#10;</xsl:text>  
<xsl:apply-templates select="skos:Concept/ns0:isUsedAs" />
<xsl:text>&#13;&#10;</xsl:text> 
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="//ns0:isUsedAs">
  <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
  <xsl:value-of select="ns0:isUsedAs[@rdf:resource]" />
 </xsl:template>

</xsl:stylesheet>

I was just trying to get the value of the attribute of skos:Concept rdf:resource with the main templates I already have, but I can't seem to print the values. I've also tried using variable:

<xsl:variable name="ns0isUsedAsvar" select="skos:Concept/ns0:isUsedAs[@rdf:resource]"/ >

And then call that variable:

<xsl:template match="//ns0:isUsedAs">
 <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
 <xsl:value-of select="$ns0isUsedAsvar" />
</xsl:template>

But I can't seem to make it work. What could be the problem? TIA!

update (in response to Eric): Here are my namespaces declaration: And I guess I was able to declare all of them. Following your cue with 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:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
  <xsl:text>&#13;&#10;</xsl:text>
  <xsl:apply-templates select="skos:Concept/ns0:isUsedAs" />
  <xsl:text>&#13;&#10;</xsl:text> 
 </xsl:for-each>
</xsl:template>

<xsl:template match="ns0:isUsedAs">
 <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
 <xsl:value-of select="@rdf:resource" />
</xsl:template>

I am instead getting the following:

START HERE
=LDR  00000nam  2200000Ia 4500
آبیس ماریزی‌ای大白叶冷杉Abies mariesii

which probably means it gets all node elements with attribute rdf:resource.

update2: particular file can be found here: http://128.199.159.143/merged-file.xml

Update3:

The transformation I am currently using can be find below, I will be adding the code in this xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:skos="http://www.w3.org/2004/02/skos/core#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:skosxl="http://www.w3.org/2008/05/skos-xl#"
 xmlns:marc="http://www.loc.gov/MARC21/slim"
 xmlns:ns0="http://art.uniroma2.it/ontologies/vocbench#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:ns1="http://art.uniroma2.it/ontologies/vocbench#"
 xmlns:void="http://rdfs.org/ns/void#">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

<xsl:template match="root">
 <xsl:for-each select="rdf:RDF">
     <xsl:text>START HERE</xsl:text>
     <xsl:text>&#13;&#10;</xsl:text>
     <xsl:text>=LDR  00000nam  2200000Ia 4500</xsl:text>
     <xsl:text>&#13;&#10;</xsl:text>
     <xsl:apply-templates select="rdf:Description/skos:narrowMatch" />
     <xsl:text>&#13;&#10;</xsl:text>
     <xsl:apply-templates select="rdf:Description/skos:exactMatch" />
     <xsl:text>&#13;&#10;</xsl:text>
     <xsl:apply-templates select="skos:Concept" />
     <xsl:text>&#13;&#10;</xsl:text>
     <xsl:apply-templates select="skos:Concept/skos:altLabel" />
     <xsl:text>&#13;&#10;</xsl:text>
 </xsl:for-each>
</xsl:template>

<xsl:template match="skos:narrowMatch">
 <xsl:text>=300  \\$a</xsl:text><xsl:value-of select="@rdf:resource" />
 <xsl:text>&#13;&#10;</xsl:text>
</xsl:template>

<xsl:template match="skos:exactMatch">
 <xsl:text>=300  \\$a</xsl:text><xsl:value-of select="@rdf:resource" />
 <xsl:text>&#13;&#10;</xsl:text>
</xsl:template>

<xsl:template match="skos:Concept[ns0:hasStatus]">
 <xsl:text>=300  \\$a</xsl:text><xsl:value-of select="@rdf:about" />
 <xsl:text>&#13;&#10;</xsl:text>
</xsl:template>

<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> 

<xsl:template match="skos:definition/skos:Description/rdf-value">
 <xsl:text>=303  \\$aDefinition$b</xsl:text><xsl:value-of select="@xml:lang" />
 <xsl:text>&#13;&#10;</xsl:text>
</xsl:template>

<xsl:template match="skos:Concept/skos:altLabel">
 <xsl:text>=304  \\$aAltLabel$b</xsl:text><xsl:value-of select="." />
 <xsl:text>$c</xsl:text>
 <xsl:value-of select="./@xml:lang" />
 <xsl:text>&#13;&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>

Update 4: The xslt that I tried that worked with a small sample based on my question:

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   ....
 xmlns:void="http://rdfs.org/ns/void#">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

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

<xsl:template match="ns0:isUsedAs">
 <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
 <xsl:value-of select="@rdf:resource" />
</xsl:template>

</xsl:stylesheet>

Solution

  • Change

    <xsl:template match="ns0:isUsedAs">
     <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
     <xsl:value-of select="@rdf:resource" />
    </xsl:template>
    

    to

    <xsl:template match="ns0:isUsedAs[@rdf:resource][1]">
     <xsl:text>=305  \\$aisUsedAs$b</xsl:text>
     <xsl:value-of select="@rdf:resource" />
    </xsl:template>
    

    If you want the template to match the first ns0:isUsedAs with an rdf:resource attribute and you want that template to only ever handle the first of these elements.

    Alternatively, if you want to leave the template as is and just match the first one with your xsl:apply-templates, you should change the apply templates line to this:

    <xsl:apply-templates select="skos:Concept/ns0:isUsedAs[@rdf:resource][1]" />