0

XML Input:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <output>
        <calls>
            <call>
                <parameters>
                    <parameter name="id">CTL-000002</parameter>
                </parameters>
                <Results>
                    <ex id="1">
                        <column name="CFGCapacity">9500.0000000</column>
                        <column name="CFGCode">CTL-3819</column>
                        <column name="CPCode">CTL-3819-01</column>
                        <column name="CPCapacity">2700</column>
                        <column name="unit">gallon</column>
                    </ex>
                    <ex id="2">
                        <column name="CFGCapacity">52120.0000000</column>
                        <column name="CFGCode">CTL-3819</column>
                        <column name="CPCode">CTL-3819-01</column>
                        <column name="CPCapacity">22950</column>
                        <column name="unit">pound</column>
                    </ex>
                    <ex id="3">
                        <column name="CFGCapacity">9500.0000000</column>
                        <column name="CFGCode">CTL-3819</column>
                        <column name="CPCode">CTL-3819-02</column>
                        <column name="CPCapacity">1700</column>
                        <column name="unit">gallon</column>
                    </ex>
                </Results>
            </call>
        </calls>
    </output>
    <plant>
        <id>CTL-000002</id>
        <plant_tag>0</plant_tag>
    </plant>
</root>

XSL:

<xsl:template match="@* | node()">
    <root>
        <xsl:for-each select="//plant">
            <xsl:choose>
                <xsl:when test="plant_tag='0'">
                    <cfgs>
                        <cfg>
                            <id>
                                <xsl:value-of select="//root/output/calls/call/parameters[parameter[@name='id'] = ./id]/../../Results/ex/column[@name='CFGCode']"/>
                            </id>
                        </cfg>
                    </cfgs>
                    <xsl:copy-of select="."/>
                </xsl:when>
                <xsl:otherwise>
                    <!--smthing else-->
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </root>
</xsl:template>
</xsl:stylesheet>

I am not sure what I am doing wrong.
Basically, I want to insert in cfg/id tag the value from the column with the name 'CFGCode'. The trick is that I may have different 'calls' with different parameters, so I want to make sure i populate the ID tag with the correct value, that's why i am trying to match the plant/ID with the parameter[name='id'] from the call. If those values match, then select the value from CFGCode.

The final objective is that, i have multiple 'plants' tags, with different information, and I need to match the plant ID with the one from the 'call' in order to select some info from my call results (these are some results from a query).

Thank you!

Edit:

Expected Output:

<root>
<plant>
    <cfgs>
        <cfg>
            <id>CTL-3819</id>
        </cfg>
    </cfgs>
    <id>CTL-000002</id>
    <plant_tag>0</plant_tag>
</plant>
</root>
user3529643
  • 105
  • 8

1 Answers1

1

The expression you want is this...

<xsl:value-of select="//root/output/calls/call/parameters[parameter[@name='id'] = current()/id]/../Results/ex/column[@name='CFGCode']"/>

Note the use of current()/id rather than ./id, as current() refers to the current node of plant whereas . in an xpath condition would refer to the parameter node.

Also note you needed to do just .. rather than ../...

However, you can simplify the expression to this...

<xsl:value-of select="//root/output/calls/call[parameters/parameter[@name='id'] = current()/id]/Results/ex/column[@name='CFGCode']"/>

Or better still define a key like so....

<xsl:key name="calls" match="call" use="parameters/parameter[@name='id']" />

Then you can do this...

<xsl:value-of select="key('calls', id)/Results/ex/column[@name='CFGCode']"/>
Tim C
  • 70,053
  • 14
  • 74
  • 93
  • thank you. if for example i would want for each unique column[@name='CPCode'] to select in different tags the values for both 'unit's [pound and gallon] from CPCapacity, I would need a similar key? I'm interested in saving the CPCapacity values for each unique CPCode – user3529643 May 09 '18 at 17:35
  • If you are using XSLT 1.0, you should read up on [Muenchian Grouping](http://www.jenitennison.com/xslt/grouping/muenchian.html) to get the unique values. If you can use XSLT 2.0, which would be much better, read up on `xsl:for-each-group`. – Tim C May 09 '18 at 17:47
  • thank you. i got the unique values by using [not(.=preceding::*)], but i am not sure on how to return the CPCapacity values...I'm using XSLT 1.0 unfortunately – user3529643 May 09 '18 at 17:48
  • 1
    It's probably a bit too much to explain in comments, so feel free to ask a whole new question, but it is definitely worth reading up on Muenchian grouping as it is a better option than checking `preceding::*` usually. – Tim C May 09 '18 at 17:50
  • Hi Tim, can you please advise on the other question https://stackoverflow.com/questions/50261381/xsl-muenchian-grouping-on-multiple-levels-and-nesting ? Thank you so much. – user3529643 May 10 '18 at 09:32