0

I am new to XSLT and I am trying to simply print one of the values of a key in XSLT3.0. Please help me with this. My XML:

<AggregatedData>
    <wd:Report_Data xmlns:wd="urn:com.workday.report/myreport">
        <wd:Report_Entry>
            <wd:Worker_ID>001</wd:Worker_ID>
            <wd:Email>[email protected]</wd:Email>
            <wd:ADlogon>TQSWD</wd:ADlogon>
            <wd:Domain>testDomain1</wd:Domain>
            <wd:Telephone>123456</wd:Telephone>
            <wd:Mobile>987456</wd:Mobile>
        </wd:Report_Entry>
        <wd:Report_Entry>
            <wd:Worker_ID>002</wd:Worker_ID>
            <wd:Email>[email protected]</wd:Email>
            <wd:ADlogon>RGTH</wd:ADlogon>
            <wd:Domain>testDomain2</wd:Domain>
            <wd:Telephone>578963</wd:Telephone>
            <wd:Mobile>5478253</wd:Mobile>
        </wd:Report_Entry>

Here is my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wd="urn:com.workday.report/myreport"
    xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
    xmlns:tube="java:com.capeclear.mediation.impl.cc.MediationTube"
    xmlns:ctx="java:com.capeclear.mediation.MediationContext"
    xmlns:functx="http://www.functx.com" exclude-result-prefixes="xs map wd functx is" version="3.0">
    <xsl:output method="text" indent="no"/>
    <xsl:template match="AggregatedData">
        <xsl:variable name="reportMap" as="map(xs:string, element()*)">
            
            <!-- Build a map from Report_Entry -->
            <xsl:map>
                <xsl:for-each select="wd:Report_Data/wd:Report_Entry">
                    <xsl:map-entry key="string(wd:Worker_ID)" >
                        <xsl:sequence>
                        <R_email><xsl:value-of select="wd:Email"/></r_email>
                        <R_ADlogon><xsl:value-of select="wd:ADlogon"/></R_ADlogon>
                        <R_Domain><xsl:value-of select="wd:Domain"/></R_Domain>
                        <R_Telephone><xsl:value-of select="wd:Telephone"/></R_Telephone>
                        <R_Mobile><xsl:value-of select="wd:Mobile"/></R_Mobile>
                        </xsl:sequence>
                  </xsl:map-entry>

                </xsl:for-each>
            </xsl:map>
        </xsl:variable>   
        <output>
        <xsl:for-each select="map:keys($reportMap)">
            <xsl:value-of select="map:get($reportMap, .)"/> 
        </xsl:for-each>
        </output>
    </xsl:template>
</xsl:stylesheet>

Current Output, this prints all the values of a key.

[email protected] TQSWD testDomain1 123456 987456
[email protected] RGTH testDomain2 578963 5478253

But I want to print only the email for key or print both email and mobile. How do I achieve it?

Expected Output1:

[email protected] 
[email protected]

Expected Output2:

[email protected] 987456
[email protected] 5478253
1
  • 1
    Well, your map value is a sequence of element nodes, the first is the email element, thus one way would be map:get($reportMap, .)[1]. map:get($reportMap, .)[self::R_email] would also work. Of course as you construct the map value, if you want to select by element name you might want to have a different map type and value, maps are often chosen as they can be more lightweight than XML trees/nodes so you could make a map holding a map and then select with map:get($reportMap, .)?email Commented 7 hours ago

1 Answer 1

0

Not sure why you need to build a map (or why, if you're going to build a map, you are populating it with XML snippets) when you can do simply:

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday.report/myreport">
<xsl:output method="text"/>

<xsl:template match="/AggregatedData">
    <xsl:value-of select="wd:Report_Data/wd:Report_Entry/wd:Email" separator="&#10;"/>
</xsl:template>

</xsl:stylesheet>

to get:

[email protected]
[email protected]

or:

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday.report/myreport">
<xsl:output method="text"/>

<xsl:template match="/AggregatedData">
    <xsl:value-of select="wd:Report_Data/wd:Report_Entry/(wd:Email||' '||wd:Mobile)" separator="&#10;"/>
</xsl:template>

</xsl:stylesheet>

to get:

[email protected] 987456
[email protected] 5478253

directly from the input XML.


Note that if your map were constructed as a map, say:

map {'entries': 
    [ 
    map {
        'Worker_ID': '001',
        'Email': '[email protected]',
        'Telephone':'123456', 
        'Mobile':'987456' 
        }, 
    map {
        'Worker_ID': '001',
        'Email': '[email protected]',
        'Telephone':'578963', 
        'Mobile':'5478253' 
        }
    ]
}

you could use:

<xsl:value-of select="$reportMap?entries?*?Email" separator="&#10;"/>

to get:

[email protected]
[email protected]
Sign up to request clarification or add additional context in comments.

Comments

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.