Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

xslt - How to split xml data inside an element using xlst?

I have xml data like this:

<Invoice >
  <cac:AllowanceCharge>
  <cbc:ChargeIndicator>false</cbc:ChargeIndicator>

  <cbc:AllowanceChargeReason>ISK:y!#x!#w!#q!#t!#</cbs:AllowanceChargeReason>

  <cbc:MultiplierFactorNumeric>0.1</cbc:MultiplierFactorNumeric>
    </Invoice>

I must split this AllowanceChargeReason by the !# characters, and put the results in an array. and loop with this array as a result i want to get this result. How can i write xslt code for below result?

<table>
<xsl:for-each >
<tr>
.......
</tr>
</xsl>
</table>

Result:

</table>
    <table>
    <tr>
      <td>
       y
      </td>
     <td>
       x
     </td>
     <td>
       w
     </td>
     <td>
       q
     </td>
    </tr> 
    </table>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To do this in XSLT 1.0, you would need to create a named template, which would call itself recursively. It would take as parameters a string to split, and the delimiter on which to split it

 <xsl:template name="split">
     <xsl:param name="text" select="." />
     <xsl:param name="delimiter" select="'!#'" />

Note, in this case the 'select' values in the parameters are default values, and would only apply if no explicit parameter is passed to the template.

In the template, you would text if the text contains the delimiter

<xsl:choose>
   <xsl:when test="contains($text, $delimiter)">

If so, you would output the first part of the string, using substring-before and then recursively call the named template using substring-after

  <td><xsl:value-of select="substring-before($text, $delimiter)" /></td>
  <xsl:call-template name="split">
       <xsl:with-param name="text" select="substring-after($text, $delimiter)" />
       <xsl:with-param name="delimiter" select="$delimiter" />
  </xsl:call-template>

When the text doesn't contain the delimiter, just output it.

For example, given the following XML

<Invoice>
  <AllowanceChargeReason>ISK:y!#x!#w!#q!#t!#</AllowanceChargeReason>
</Invoice>

And the following XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes"/>
    <xsl:template match="AllowanceChargeReason">
        <table>
            <tr>
                <xsl:call-template name="split">
                    <xsl:with-param name="text" select="substring-after(., ':')" />
                </xsl:call-template>
            </tr>
        </table>
    </xsl:template>

    <xsl:template name="split">
        <xsl:param name="text" select="." />
        <xsl:param name="delimiter" select="'!#'" />

        <xsl:if test="$text != ''">
            <xsl:choose>
                <xsl:when test="contains($text, $delimiter)">
                    <td><xsl:value-of select="substring-before($text, $delimiter)" /></td>
                    <xsl:call-template name="split">
                        <xsl:with-param name="text" select="substring-after($text, $delimiter)" />
                        <xsl:with-param name="delimiter" select="$delimiter" />
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <td><xsl:value-of select="$text" /></td>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Then the following is output

<table>
   <tr>
      <td>y</td>
      <td>x</td>
      <td>w</td>
      <td>q</td>
      <td>t</td>
   </tr>
</table>

Do note you will have to take into account namespaces when you apply this to your actual XML sample.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...