Search code examples
xmlxsltlibxslt

xslt nested select from xml node value


I've already reviewed some of the other posts regarding nested selects and don't believe that they address my use case. Essentially I am trying to create a user account in another system through a web service and need to pass a Login ID that originates from a field in my xml which could essentially be almost anything, such as employee id, email address, UUID, etc. The field to use will come from a configuration value that goes into the generation of the xml. I've abbreviated my xml and xslt for simplicity, so please don't suggest that I use a choose or if statement as I need to keep the possible xml fields to choose from wide open.

Sample XML:

<root>
  <General>
    <Name Prefix="MR" First="Mickey" Middle="M" Last="Mouse" Suffix="I" Title="BA" Gender="M" BirthMonth="02" BirthDay="26" BirthYear="1984"/>
    <Email Work="test9999@acme.com" Home="Homeemail@gmail.com"/>
    <EmployeeId>9948228</EmployeeId>
  </General>
  <ConfigProperties>
    <LoginID>root/General/EmployeeId</LoginID>
  </ConfigProperties>
</root>

XSL Sample:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="yes" />
<xsl:template match="/">
  <Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:variable name="xxLI" select="root/ConfigProperties/LoginID" />
    <xsl:attribute name="LoginId"><xsl:value-of select="$xxLI"/></xsl:attribute>
  </Response>
</xsl:template>
</xsl:stylesheet>

Transformed XML:

<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          LoginId="root/General/EmployeeId"/>

What I'm really hoping to get back is something like:

<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          LoginId="9948228"/>

I'm stumped. Any thoughts?


Solution

  • There is no way to do this in plain XSLT 1, but if your XSLT processor supports the "dynamic" extension (XALAN supports it), you can do this:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:dyn="http://exslt.org/dynamic"
        extension-element-prefixes="dyn">
    
        <xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="yes" />
        <xsl:template match="/">
            <Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <xsl:variable name="xxLI" select="root/ConfigProperties/LoginID" />
                <xsl:attribute name="LoginId"><xsl:value-of select="dyn:evaluate($xxLI)"/></xsl:attribute>
            </Response>
        </xsl:template>
    </xsl:stylesheet>
    

    I tested this in Oxygen/XML using XALAN and got this output

    <?xml version="1.0" encoding="utf-8"?>
    <Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" LoginId="9948228"/>