简体   繁体   中英

How to restrict a for-each loop with some condition using XSLT 1.0?

I have this XML code and I want my for loop to run/display only values for specific type num- 10,20,180

<input>
<name>Jack</name>
<age>23</age>
<type-10-num>1</type-10-num>
<type-20-num>2</type-20-num>
<type-20-char>3</type-20-char>
<type-180-num>4</type-180-num>
<type-180-char>5</type-180-char>
<type-180-str>6</type-180-str>
</input>

I'm running a for-each loop for checking the type node-

<xsl:for-each select="exslt:node-set($input)/*[starts-with(name(),'type-')]">

And fetching the type value from it in a variable-

 <xsl:variable name="fetchValue">               
                        <xsl:value-of select="substring-before(substring-after(name(), '-'), '-')" />                   
                    </xsl:variable>

But I want my for loop to run one time for each values 10,20,180. If type-20 occurs 2 times I want it to run one time for each 20 and then go to next 180. So total it should run 3 times or lets just say I want to print some details related to these 3 values (so it should not repeat).

You can use substring-after two times to check for an ending num . A separate variable is not necessary.

<xsl:for-each select="exslt:node-set($input)/*[starts-with(name(),'type-') and substring-after(substring-after(name(),'-'),'-') = 'num']">
  <xsl:value-of select="."/> </xsl:text>
</xsl:for-each>

Output is:

1 2 4

If you want to match only these exact names, you could select them directly:

<xsl:for-each select="exslt:node-set($input)/*[self::type-10-num or self::type-20-num or self::type-180-num]">
  <xsl:value-of select="."/><xsl:text> </xsl:text>
</xsl:for-each>

Output is the same.

This transformation :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match=
        "*[starts-with(name(), 'type-')
         and substring(name(), string-length(name())-2) = 'num'
         ]">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="text()"/>
</xsl:stylesheet>

when applied on the provided XML document (formatted for readability):

<input>
    <name>Jack</name>
    <age>23</age>
    <type-10-num>1</type-10-num>
    <type-20-num>2</type-20-num>
    <type-20-char>3</type-20-char>
    <type-180-num>4</type-180-num>
    <type-180-char>5</type-180-char>
    <type-180-str>6</type-180-str>
</input>

Produces data for each of the elements with name type-XYZ-num:

<type-10-num>1</type-10-num>
<type-20-num>2</type-20-num>
<type-180-num>4</type-180-num>

One can replace this code in the matching template:

<xsl:copy-of select="."/>

with whatever is necessary in the particular problem being solved.

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