tags:

views:

47

answers:

2

I have to files XML files: language.xml and menu.xml. The first one is loaded by default, the second is loaded with <xsl:param />.

language.xml:

<?xml version="1.0" encoding="utf-8"?>
<language>
    <header>
        <menu>
            <title>Title of example</title>
        </menu>
        <menu>
            <title>Title of example 2</title>
        </menu>
        <menu>
            <title>Title of example 3</title>
        </menu>
    </header>
</language>

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<header>
    <menu>
        <a>/example</a>
    </menu>
    <menu>
        <a>/example2</a>
    </menu>
    <menu>
        <a>/example3</a>
    </menu>
</header>

I need to match every /language/header/menu with every /header/menu. The positions are correct, so the first /language/header/menu corresponds with /header/menu.

So the desired output will be:

<a href="/example">Title of example</a>
<a href="/example2">Title of example 2</a>
<a href="/example3">Title of example 3</a>

Thanks!

A: 

From what I understand you are saying the files should be linked based on their position as XML child nodes. In which case you want something like:

<xsl:for-each select="menu">
  <a href="{.}">
    <xsl:variable name="position"><xsl:value-of select="position()"/></xsl:variable>
    <xsl:for-each select="$param//menu[position() = $position]">
      <xsl:value-of select="title"/>
    </xsl:for-each>
  </a>
</xsl:for-each>
Nick Jones
+3  A: 

Using match templates you can do the following:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="xml" indent="yes"/>

  <xsl:variable name="localization" select="document('index.en.xml')" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <xsl:apply-templates />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="menu">
    <a href="{a}">
      <xsl:variable name="pos" select="position()" />
      <xsl:value-of select="$localization/language/header/menu[$pos]/title"/>
    </a>
  </xsl:template>

</xsl:stylesheet>
0xA3
@0xA3: This is answer is rigth, but I think it has a typo: `apply-imports` should be `apply-templates`...
Alejandro
@Alejandro: Thanks for the hint. It probably happened due to auto-completion and I didn't notice it because it works too (but makes no sense).
0xA3
@0xA3: Also, +1 for an answer ussing pattern matching.
Alejandro
It's possible to have a variable in document()? I've tried but seems not to work. Like: `<xsl:variable name="locale" select="language/language" />` and then `<xsl:variable name="localitzation" select="document('index.$locale.xml')" />` . Thanks in advance!
Isern Palaus
@Isern Palaus: It is possible, but it requires you to use the `concat()` function to concatenate the strings explicitly (that's different from languages like PHP or Perl): `<xsl:variable name="localitzation" select="document(concat('index.', $locale, '.xml')" />`
0xA3
@Isern Palaus: Also may need (with some processors) the use of p/2 `fn:document` for base URI like `document(concat('index.', $locale, '.xml'),/)`
Alejandro