Terence
Terence

Reputation: 11088

XSLT combination from two lists

Ive got a list of values in A, and a list of values in B. I want to output the values of A, (or repeat) for the amount of values in B. Thus if we have 4 values in B, we repeat the 3 values in A, 4 times.

ex

  <a>
   <v>1</v>
   <v>2</v>
   <v>3</v>
  </a>
  <b>
   <v>y</v>
   <v>z</v>
  </b>

should result into

  <x>1</x>
  <x>2</x>
  <x>3</x>
  <x>1</x>
  <x>2</x>
  <x>3</x>

this is what I've tried

  <xsl:foreach select="a/v">
    <xsl:foreach select="b/v">
      <x><xsl:value-of select="."></x>
    </xsl:foreach>
  </xsl:foreach>

Upvotes: 0

Views: 404

Answers (2)

Neijwiert
Neijwiert

Reputation: 1025

Given input XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <a>
    <v>1</v>
    <v>2</v>
    <v>3</v>
  </a>
  <b>
    <v>y</v>
    <v>z</v>
  </b>
</root>

And the 1.0 XSLT stylesheet:

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
  <xsl:apply-templates select="b/v"/>
</xsl:template>

<xsl:template match="b/v">
  <xsl:apply-templates select="../../a/v"/>
</xsl:template>

<xsl:template match="a/v">
  <x><xsl:value-of select="."/></x>
</xsl:template>

</xsl:stylesheet>

Gives output:

123123

Best to avoid using for-each loops and use templates instead.

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 116957

Given a well-formed input:

XML

<root>
  <a>
    <v>1</v>
    <v>2</v>
    <v>3</v>
  </a>
  <b>
    <v>y</v>
    <v>z</v>
  </b>
</root>

the following stylesheet:

XST 1.0

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

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="b/v">
            <xsl:for-each select="/root/a/v">
                <x><xsl:value-of select="."/></x>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

will return:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <x>1</x>
  <x>2</x>
  <x>3</x>
  <x>1</x>
  <x>2</x>
  <x>3</x>
</root>

A slightly more efficient version:

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

<xsl:template match="/root">
    <xsl:variable name="a">
        <xsl:for-each select="a/v">
            <x><xsl:value-of select="."/></x>
        </xsl:for-each>
    </xsl:variable>
    <xsl:copy>
        <xsl:for-each select="b/v">
            <xsl:copy-of select="$a"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions