简体   繁体   中英

HashMap iteration in XSLT 2.0

I have an HashMap object as part of my java model and when I convert it into XML, this is the result...

<transaction>
  <claims>
    <remarksMap>
      <entry>
        <string>XX</string>
        <string>Description 1</string>
      </entry>
      <entry>
        <string>YYY</string>
        <string>Description 2</string>
      </entry>
      <entry>
        <string>ZZZZ</string>
        <string>Description 3</string>
      </entry>
    </remarksMap>
  </claims>
</transaction>

I would like to iterate through the Map object in XSLT but haven't had any luck yet. Posting a sample code from the XSL...

<xsl:for-each select="remarksMap/entry">
  <fo:table-row>
    <fo:table-cell padding="3px" text-align="left">
      <fo:block font-size="7pt">
        <xsl:value-of select="string" />
      </fo:block>
    </fo:table-cell>
  </fo:table-row>
</xsl:for-each>

The Output for this comes like this. It's printing out the entrySet() in a new line. XX Description 1 YYY Description 2 ZZZZ Description 3

I would ideally like to print the keys in the first and the values in the second . Appreciate any help on this!

PS: I'm using XSL v2.0 and Saxon-HE:9.4 as the processor.

What you would need to do is add a second xsl:for-each to loop over each string and create the fo:table-cell 's from that.

<xsl:for-each select="remarksMap/entry">
    <fo:table-row>
        <xsl:for-each select="string">
            <fo:table-cell padding="3px" text-align="left">
                <fo:block font-size="7pt">
                    <xsl:value-of select="."/>
                </fo:block>
            </fo:table-cell>                                
        </xsl:for-each>
    </fo:table-row>
</xsl:for-each>

You could also use a push style approach...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/*">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
                    <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="my-page">
                <fo:flow flow-name="xsl-region-body"> 
                    <xsl:apply-templates/>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

    <xsl:template match="entry">
        <fo:table-row>
            <xsl:apply-templates/>
        </fo:table-row>
    </xsl:template>

    <xsl:template match="string">
        <fo:table-cell padding="3px" text-align="left">
            <fo:block font-size="7pt">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:table-cell>        
    </xsl:template>

</xsl:stylesheet>

XSL-FO Output

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
         <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="my-page">
      <fo:flow flow-name="xsl-region-body">
         <fo:table-row>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">XX</fo:block>
            </fo:table-cell>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">Description 1</fo:block>
            </fo:table-cell>
         </fo:table-row>
         <fo:table-row>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">YYY</fo:block>
            </fo:table-cell>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">Description 2</fo:block>
            </fo:table-cell>
         </fo:table-row>
         <fo:table-row>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">ZZZZ</fo:block>
            </fo:table-cell>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">Description 3</fo:block>
            </fo:table-cell>
         </fo:table-row>
      </fo:flow>
   </fo:page-sequence>
</fo:root>

Edit

After reading your question a second time, this:

I would ideally like to print the keys in the first and the values in the second .

almost sounds like you want just two cells with all keys in the first cell and all values in the second. If this is the case, you could do something like...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/*/claims/remarksMap">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
                    <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="my-page">
                <fo:flow flow-name="xsl-region-body"> 
                    <fo:table-row>
                        <fo:table-cell padding="3px" text-align="left">
                            <fo:block font-size="7pt">
                                <xsl:value-of select="entry/string[1]" separator=", "/>
                            </fo:block>
                        </fo:table-cell>        
                        <fo:table-cell padding="3px" text-align="left">
                            <fo:block font-size="7pt">
                                <xsl:value-of select="entry/string[2]" separator=", "/>
                            </fo:block>
                        </fo:table-cell>        
                    </fo:table-row>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

</xsl:stylesheet>

XSL-FO Output

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
         <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="my-page">
      <fo:flow flow-name="xsl-region-body">
         <fo:table-row>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">XX, YYY, ZZZZ</fo:block>
            </fo:table-cell>
            <fo:table-cell padding="3px" text-align="left">
               <fo:block font-size="7pt">Description 1, Description 2, Description 3</fo:block>
            </fo:table-cell>
         </fo:table-row>
      </fo:flow>
   </fo:page-sequence>
</fo:root>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM