質問

I will precede this with the fact that I am new to XSLT (1.0 in this case) and have had little luck on getting this resolved on my own. I have the following XML:

<Root>
<Info>
    <Feature>SEA</Feature>
    <Sequence>10</Sequence>
    <Value>Y</Value>
</Info>
<Info>
    <Feature>SEA</Feature>
    <Sequence>20</Sequence>
    <Value>Y</Value>
</Info>
<Info>
    <Feature>TEL</Feature>
    <Sequence>10</Sequence>
    <Value>N</Value>
</Info>
<Info>
    <Feature>TEL</Feature>
    <Sequence>20</Sequence>
    <Value>Y</Value>
</Info>
<Info>
    <Feature>TEL</Feature>
    <Sequence>35</Sequence>
    <Value>Y</Value>
</Info>
</Root>

I need to evaluate all the Features equal to SEA against all the Features equal to TEL where the Sequence is the same. The output would include both the original SEA value, and the TEL value.

Output request is:

<Root>
<Info>
    <Feature>SEA</Feature>
    <Sequence>10</Sequence>
    <SEAValue>Y</SEAValue>
    <TELValue>N</TELValue>
</Info>
<Info>
    <Feature>SEA</Feature>
    <Sequence>20</Sequence>
    <SEAValue>Y</SEAValue>
    <TELValue>Y</TELValue>  
</Info>
</Root>
役に立ちましたか?

解決

The simplest and most efficient way to do joins in XSLT is with a key. Declare a key:

<xsl:key name="k" match="Info[Feature='TEL']" use="Sequence"/>

and then you can do

<xsl:for-each select="Info[Feature='SEA']">
  <xsl:copy-of select="Feature"/>
  <xsl:copy-of select="Sequence"/>
  <SEAValue><xsl:value-of select="value"/></SEAValue>
  <TELValue><xsl:value-of select="key('k', Sequence)/Value"/></TELValue>
</xsl:for-each>

他のヒント

You may try this key based solution:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>
    <xsl:key name="kSequence" match="Info" use="Sequence"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Info/Value" >
        <xsl:element name="{../Feature}Value" >
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/*" >
        <xsl:copy>
            <xsl:for-each select="//Info[count( . | key('kSequence', Sequence)[1])=1]" >
                <xsl:variable name="is" select="key('kSequence', current()/Sequence)" />
                <xsl:if test="$is[Feature = 'SEA'] and $is[Feature = 'TEL']" >
                    <xsl:copy>
                        <xsl:apply-templates select="$is[Feature = 'SEA']/*" />
                        <xsl:apply-templates select="$is[Feature = 'TEL']/Value" />
                    </xsl:copy>
                </xsl:if>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top