0

I need help where I can store two xslt variables in 1 array like variable to be used later

    <xsl:variable name="edgeDeviceArray">
        <Item><xsl:value-of select="$edgeDev1" /></Item>
        <Item><xsl:value-of select="$edgeDev2" /></Item>
    </xsl:variable> 

But the output of the above seems to be concatenation. I would like to refer later like edgeDeviceArray[1]...

Here is a (non-working) fragment of my stylesheet demonstrating what I am trying to do

    <xsl:variable name="edgeDev1"
        select="$deviceDoc/x:config/t:devices/t:device[t:address=$edgeDev1IP]/t:name" />
    <xsl:variable name="edgeDev2"
        select="$deviceDoc/x:config/t:devices/t:device[t:address=$edgeDev2IP]/t:name" />
    <xsl:variable name="xrSet" select="$xrDeviceDoc/x:config/t:devices/t:device-module/t:devices" />

    <xsl:for-each select="$xrSet">
      <xsl:variable name="asideDoc"
          select="document(concat($edgeDevice[position()], '.xml'))" />
    </xsl:for-each>

Here, I am reading the devices names from 1 doc based on certain attributes if they match.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:t="http://tail-f.com/ns/ncs"
    xmlns:x="http://tail-f.com/ns/config/1.0" 
    xmlns:y="http://tail-f.com/ned/alu-sr"
    xmlns:a="http://tail-f.com/ned/cisco-ios-xr"
    xmlns:m="http://mask.data"
    xmlns:im="http://inverse-mask.data" exclude-result-prefixes="xsl t x y"
    xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">

  <xsl:output method="xml" version="1.0" encoding="UTF-8"
      indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <xsl:variable name="deviceDoc" select="document('devices.xml')" />
    <xsl:variable name="edgeDev1IP"
        select="../y:sdp[y:sdp-id=$sdpSet[1]]/y:far-end" />
    <xsl:variable name="edgeDev1"
        select="$deviceDoc/x:config/t:devices/t:device[t:address=$edgeDev1IP]/t:name" />
    <xsl:variable name="edgeDev2IP"
        select="../y:sdp[y:sdp-id=$sdpSet[2]]/y:far-end" />
    <xsl:variable name="edgeDev2"
        select="$deviceDoc/x:config/t:devices/t:device[t:address=$edgeDev2IP]/t:name" />
    <xsl:variable name="xrDeviceDoc" select="document('xrDevices.xml')" />
    <xsl:variable name="xrSet"
        select="$xrDeviceDoc/x:config/t:devices/t:device-module/t:devices" />
    <xsl:variable name="edgeDeviceArray">
      <item><xsl:value-of select="$edgeDev1" /></item>
      <item><xsl:value-of select="$edgeDev2" /></item>
    </xsl:variable> 

    <anurag><xsl:value-of select="exsl:node-set($edgeDeviceArray)/item[1]" /></anurag>
  </xsl:template>
</xsl:stylesheet> 
12
  • 1
    Are you using XSLT 1.0 or 2.0? Commented May 31, 2017 at 13:31
  • I am using XSLT 1.0. Thx Commented May 31, 2017 at 14:02
  • You cannot do this in XSLT 1.0 without extensions, though you can get a close approximation if the two variables' values are node sets of one node each. If you explain the purpose for which you wanted it, then perhaps we can suggest a better approach. Commented May 31, 2017 at 14:04
  • I have a loop where I want to refer the above devices and thats why I want to put them in some reference. I am reading the devices from different xml files and I store them in these two variables. Commented May 31, 2017 at 14:08
  • Thanks, @Anurag, but in order to help you, I think we are going to need to see a minimal reproducible example demonstrating the problem. Commented May 31, 2017 at 14:10

1 Answer 1

1

I would like to refer later like edgeDeviceArray[1]

That won't work for two reasons:

  1. There's only one edgeDeviceArray. In order to refer to its first item, you would need to use something like $edgeDeviceArray/item[1];
  2. In XSLT 1.0, your variable is a result tree fragment, and must be converted to a node-set before its contents can be addressed by XPath.

Here's a minimized example:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="myVar">
    <item>A</item>
    <item>B</item>
</xsl:variable> 

<xsl:template match="/">
    <result>
        <xsl:value-of select="exsl:node-set($myVar)/item[2]"/>
    </result>
</xsl:template>

</xsl:stylesheet>

Result

<?xml version="1.0" encoding="UTF-8"?>
<result>B</result>
Sign up to request clarification or add additional context in comments.

4 Comments

<xsl:variable name="edgeDeviceArray"> <Item><xsl:value-of select="$edgeDev1" /></Item> <Item><xsl:value-of select="$edgeDev2" /></Item> </xsl:variable> <anurag><xsl:value-of select="exsl:node-set($edgeDeviceArray)/Item[1]" /></anurag>
Did U mean the above? I can't put template match as it is there outside. I am always getting empty output
@Anurag I am afraid I cannot help you with code that I cannot reproduce.
@Anurag My answer stands. <xsl:value-of select="exsl:node-set($edgeDeviceArray)/Item[1]" /> should return the same as <xsl:value-of select="$edgeDev1" />.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.