tags:

views:

410

answers:

4

Sample XML:

  <term>
  <name>facies</name> 
  <translation language="en">facies</translation> 
  <definition><num>1.</num> cara <num>2.</num> superficie externa, superficie anterior</definition> 
  </term>
  <term>
  <name>factores angiógenos</name> 
  <translation language="en">angiogenic factors</translation> 
  <definition>descripción de sustancias que favorecen el desarrollo o la formación nueva de vasos sanguíneos</definition> 
  </term>
  <term>
  <name>factores de la coagulación</name> 
  <translation language="en">coagulation factors</translation> 
  <definition>la cascada de la coagulación de la sangre consta de 12 factores en total, todos ellos necesarios para que funcione bien</definition> 
  </term>

I have an XSLT file which makes a list of names mapped to name, and a translation if one exists.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="terms">

    var allwords = [

    <xsl:for-each select="letter">
      <xsl:for-each select="term">
        <xsl:call-template name="term"></xsl:call-template>
      </xsl:for-each>
    </xsl:for-each>
  ['','']
    ];

  </xsl:template>

  <xsl:template name="term">
    ['<xsl:value-of select="name"/>', '<xsl:value-of select="name"/>'],

    <xsl:if test="name!=translation">
      ['<xsl:value-of select="translation"/>', '<xsl:value-of select="name"/>'],
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

This works out great, producing the following

var allwords = 
[ ['facies', 'facies'], 
['factores angiógenos', 'factores angiógenos'],  
['angiogenic factors', factores angiógeno],
['factores de la coagulació', 'factores de la coagulació'] 
etc...

However, as you can see the first part in the array is not in alphabetical order any more, because of the addition of the english word.

It needs to be in alphabetical order, so in this case "angiogenic factors" would be the first element in the array

Any ideas?

+1  A: 

<xsl:sort>

annakata
A: 

Yeah, needs a little more thought that just sort :p

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="terms">

    var allwords = [

      <xsl:for-each select="letter/term/name | letter/term/translation">
        <xsl:sort order="ascending" select="."/>
        <xsl:call-template name="term"></xsl:call-template>
      </xsl:for-each>
  ['','']
    ];

  </xsl:template>

  <xsl:template name="term">
    ['<xsl:value-of select="."/>', '<xsl:value-of select="./../name"/>'],
  </xsl:template>

</xsl:stylesheet>

Basically, you need to be able to select both names and translations, then sort by both of them. Then the template had to be edited a bit, as it was now receiving the child elements rather than the parent.

qui
Neither of these templates match your schema at all. Also "for-each" is not the appropriate element for what you are trying to do -- "apply-templates" is the relevant construction.
Ishmael
A: 

Here is my best guess at what you are trying to do. Given the following sample XML:

<terms>
<letter name="f">
 <term>
  <name>facies</name>
  <translation language="en">facies</translation>
  <definition>
   <num>1.</num> cara <num>2.</num> superficie externa, superficie anterior
  </definition>
 </term>
 <term>
  <name>factores angiógenos</name>
  <translation language="en">angiogenic factors</translation>
  <definition>descripción de sustancias que favorecen el desarrollo o la formación nueva de vasos sanguíneos</definition>
 </term>
 <term>
  <name>factores de la coagulación</name>
  <translation language="en">coagulation factors</translation>
  <definition>la cascada de la coagulación de la sangre consta de 12 factores en total, todos ellos necesarios para que funcione bien</definition>
 </term>
</letter>

Sort on the translation for each letter:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

<xsl:output omit-xml-declaration="yes"/>

<xsl:template match="terms">
 var allwords = [
  <xsl:apply-templates select="letter">
   <xsl:sort select="name"/>
  </xsl:apply-templates>
 ];
</xsl:template>

<xsl:template match="letter">
 <xsl:apply-templates select="term">
  <xsl:sort select="translation"/>
 </xsl:apply-templates>
</xsl:template>

<xsl:template match="term">
 ['<xsl:value-of select="translation"/>', '<xsl:value-of select="name"/>']
 <xsl:if test="not(position() = last())">
  <xsl:text>, </xsl:text>
 </xsl:if>
</xsl:template>

Ishmael
A: 

I think it is that simple:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output encoding="windows-1252" omit-xml-declaration="yes"/>

  <xsl:template match="/*">
    var allwords = [
    <xsl:apply-templates select="term">
      <!-- key to success -->
      <xsl:sort select="name"/>
    </xsl:apply-templates>
    ];
  </xsl:template>

  <xsl:template match="term">
    ['<xsl:value-of select="name" />', 
    '<xsl:value-of select="translation[@language='en']" />']
    <xsl:if test="position() != last()">,</xsl:if>
  </xsl:template>
</xsl:stylesheet>

Output (sorry, had to remove "funny" characters from the test input)

var allwords = [
  ['facies', 'facies'],
  ['factores angiogenos', 'angiogenic factors'],
  ['factores de la coagulacio', 'coagulation factors']
];

(Line breaks and indentation are a little different in original output. I changed them so it looks nice.)

I think you were unaware of <xsl:sort/>, marked with <!-- key to success --> in the XSL stylesheet. ;-)

Tomalak