Comment obtenir une valeur d'attribut lors de l'utilisation de XSLT avec un espace de nom inconnu?

StackOverflow https://stackoverflow.com/questions/76204

  •  09-06-2019
  •  | 
  •  

Question

Je reçois un flux 3ème partie dont je ne peux pas être certain de l'espace de noms. Je dois donc actuellement utiliser la fonction local-name () dans mon XSLT pour obtenir les valeurs des éléments. Cependant, je dois obtenir un attribut d'un tel élément et je ne sais pas comment faire cela lorsque les espaces de noms sont inconnus (d'où la nécessité de la fonction local-name ()).

N.B. J'utilise .net 2.0 pour traiter le XSLT

Voici un exemple du code XML:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <id>some id</id>
   <title>some title</title>
   <updated>2008-09-11T15:53:31+01:00</updated>
   <link rel="self" href="http://www.somefeedurl.co.uk" />
   <author>
      <name>some author</name>
      <uri>http://someuri.co.uk</uri>
   </author>
   <generator uri="http://aardvarkmedia.co.uk/">AardvarkMedia script</generator>
   <entry>
      <id>http://soemaddress.co.uk/branded3/80406</id>
      <title type="html">My Ttile</title>
      <link rel="alternate" href="http://www.someurl.co.uk" />
      <updated>2008-02-13T00:00:00+01:00</updated>
      <published>2002-09-11T14:16:20+01:00</published>
      <category term="mycategorytext" label="restaurant">Test</category>
      <content type="xhtml">
         <div xmlns="http://www.w3.org/1999/xhtml">
            <div class="vcard">
               <p class="fn org">some title</p>
               <p class="adr">
                  <abbr class="type" title="POSTAL" />
                  <span class="street-address">54 Some Street</span>
                  ,
                  <span class="locality" />
                  ,
                  <span class="country-name">UK</span>
               </p>
               <p class="tel">
                  <span class="value">0123456789</span>
               </p>
               <div class="geo">
                  <span class="latitude">51.99999</span>
                  ,
                  <span class="longitude">-0.123456</span>
               </div>
               <p class="note">
                  <span class="type">Review</span>
                  <span class="value">Some content</span>
               </p>
               <p class="note">
                  <span class="type">Overall rating</span>
                  <span class="value">8</span>
               </p>
            </div>
         </div>
      </content>
      <category term="cuisine-54" label="Spanish" />
      <Point xmlns="http://www.w3.org/2003/01/geo/wgs84_pos#">
         <lat>51.123456789</lat>
         <long>-0.11111111</long>
      </Point>
   </entry>
</feed>

Ceci est XSLT

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:wgs="http://www.w3.org/2003/01/geo/wgs84_pos#" exclude-result-prefixes="atom wgs">
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="uniqueVenuesKey" match="entry" use="id"/>
  <xsl:key name="uniqueCategoriesKey" match="entry" use="category/@term"/>

  <xsl:template match="/">
    <locations>
      <!-- Get all unique venues -->
      <xsl:for-each select="/*[local-name()='feed']/*[local-name()='entry']">
        <xsl:variable name="CurrentVenueKey" select="*[local-name()='id']" ></xsl:variable>
        <xsl:variable name="CurrentVenueName" select="*[local-name()='title']" ></xsl:variable>
        <xsl:variable name="CurrentVenueAddress1" select="*[local-name()='content']/*[local-name()='div']/*[local-name()='div']/*[local-name()='p'][@class='adr']/*[local-name()='span'][@class='street-address']" ></xsl:variable>
        <xsl:variable name="CurrentVenueCity" select="*[local-name()='content']/*[local-name()='div']/*[local-name()='div']/*[local-name()='p'][@class='adr']/*[local-name()='span'][@class='locality']" ></xsl:variable>
        <xsl:variable name="CurrentVenuePostcode" select="*[local-name()='postcode']" ></xsl:variable>
        <xsl:variable name="CurrentVenueTelephone" select="*[local-name()='telephone']" ></xsl:variable>
        <xsl:variable name="CurrentVenueLat" select="*[local-name()='Point']/*[local-name()='lat']" ></xsl:variable>
        <xsl:variable name="CurrentVenueLong" select="*[local-name()='Point']/*[local-name()='long']" ></xsl:variable>
        <xsl:variable name="CurrentCategory" select="WHATDOIPUTHERE"></xsl:variable>

            <location>
              <locationName>
                <xsl:value-of select = "$CurrentVenueName" />
              </locationName>
              <category>
                <xsl:value-of select = "$CurrentCategory" />
              </category>
              <description>
                  <xsl:value-of select = "$CurrentVenueName" />
              </description>
              <venueAddress>
                <streetName>
                  <xsl:value-of select = "$CurrentVenueAddress1" />
                </streetName>
                <town>
                  <xsl:value-of select = "$CurrentVenueCity" />
                </town>
                <postcode>
                  <xsl:value-of select = "$CurrentVenuePostcode" />
                </postcode>
                <wgs84_latitude>
                  <xsl:value-of select = "$CurrentVenueLat" />
                </wgs84_latitude>
                <wgs84_longitude>
                  <xsl:value-of select = "$CurrentVenueLong" />
                </wgs84_longitude>
              </venueAddress>
              <venuePhone>
                <phonenumber>
                  <xsl:value-of select = "$CurrentVenueTelephone" />
                </phonenumber>
              </venuePhone>
          </location>
        </xsl:for-each>
    </locations>
  </xsl:template>
</xsl:stylesheet>

J'essaie de remplacer le code approprié par la variable $ CurrentCategory pour afficher mycategorytext

Était-ce utile?

La solution

Je n'ai pas d'éditeur XSLT ici, mais avez-vous essayé d'utiliser

*[local-name()='category']/@*[local-name()='term']

Autres conseils

Selon http: // www. w3.org/TR/2006/nom-REC-xml-20060816/#scoping-defaulting

" Les déclarations d'espace de nom par défaut ne s'appliquent pas directement aux noms d'attributs; l'interprétation des attributs non préfixés est déterminée par l'élément sur lequel ils apparaissent. "

Cela signifie que vos attributs ne sont pas dans un espace de noms. Il suffit d'utiliser "@ terme".

Pour être un peu plus clair, il n’est pas nécessaire d’utiliser local-name () pour résoudre ce problème. La manière conventionnelle de le traiter serait de déclarer un préfixe pour l'espace de noms atom dans votre XSLT, puis de l'utiliser dans vos requêtes xpath.

Vous avez déjà cette déclaration sur votre élément de feuille de style (xmlns: atom = "http: //www.w3.org/2005/Atom"), il ne reste donc plus qu'à l'utiliser.

Comme je l'ai déjà expliqué, l'attribut n'est pas affecté par l'espace de nom par défaut. Votre code devrait alors ressembler à ceci (en supposant que vous deviez ajouter & xmlns: xhtns = ' http://www.w3.org/1999/xhtml '"):

      <xsl:for-each select="/atom:feed/atom:entry">
        <xsl:variable name="CurrentVenueKey" select="atom:id" />
        <xsl:variable name="CurrentVenueName" select="atom:title" />
        <xsl:variable name="CurrentVenueAddress1" 
             select="atom:content/xhtml:div/xhtml:div/xhtml:p[@class='adr']/xhtml:span[@class='street-address']" />
        <xsl:variable name="CurrentVenueCity" 
             select="atom:content/xhtml:div/xhtml:div'/xhtml:p[@class='adr']/xhtml:span[@class='locality'] />
...
        <xsl:variable name="CurrentCategory" select="atom:category/@term" />

..... 

local-name () peut être très utile si vous ne connaissez pas vraiment la structure du XML que vous êtes en train de transformer, mais dans ce cas, si vous recevez autre chose que ce que vous attendez, cela se brisera Cas.

Je ne suis pas vraiment sûr de la raison pour laquelle vous devez utiliser local-name (), mais si vous partagez un peu plus d'informations sur le processeur xslt que vous utilisez avec le langage, je serai capable de comprendre . Je dis ce b / c, vous devriez être capable de faire quelque chose comme:

<xsl:stylesheet xmlns="http://www.w3.org/2005/Atom" ..>

<xsl:template match="feed">
  <xsl:apply-templates />
</xsl:template>

<xsl:template match="entry">
  ... 
  <xsl:variable name="current-category" select="category/@term" />
  ...
</xsl:template>

Les deux choses que j'espère vous aider sont la déclaration xmlns en haut sans préfixe. Cela définit l’espace de noms par défaut afin que vous n’ayez pas à utiliser les préfixes d’espace de noms. De même, vous pouvez appeler do 'xmlns: a = http: //www.w3.org/2005/Atom"' puis faites 'select = "a: feed". L'autre chose à noter est d'utiliser le '@term' qui sélectionne les attributs. Si vous voulez apparier n'importe quel attribut, "@ *" fonctionne exactement comme pour les éléments.

Encore une fois, en fonction du processeur, d’autres outils utiles sont à votre disposition. Par conséquent, si vous pouviez fournir un peu plus d’informations, cela pourrait aider. En outre, la liste de diffusion XSL pourrait être une autre ressource utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top