XSLT - remove whitespace from template

前端 未结 8 1794
北恋
北恋 2020-12-02 13:23

I am using XML to store a small contact list and trying to write a XSL template that will transform it into a CSV file. The problem I am having is with whitespace in the out

相关标签:
8条回答
  • 2020-12-02 13:42

    As far as removing tabs but retaining separate lines, I tried the following XSLT 1.0 approach, and it works rather well. Your use of version 1.0 or 2.0 largely depends on which platform you're using. It looks like .NET technology is still dependant on XSLT 1.0, and so you're limited to extremely messy templates (see below). If you're using Java or something else, please refer to the much cleaner XSLT 2.0 approach listed towards the very bottom.

    These examples are meant to be extended by you to meet your specific needs. I'm using tabs here as an example, but this should be generic enough to be extensible.

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <text>
            adslfjksdaf
    
                    dsalkfjdsaflkj
    
                lkasdfjlsdkfaj
    </text>
    

    ...and the XSLT 1.0 template (required if you use .NET):

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet  
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">   
     <xsl:template name="search-and-replace">
       <xsl:param name="input"/>
       <xsl:param name="search-string"/>
       <xsl:param name="replace-string"/>
       <xsl:choose>
        <xsl:when test="$search-string and 
                        contains($input,$search-string)">
           <xsl:value-of
               select="substring-before($input,$search-string)"/>
           <xsl:value-of select="$replace-string"/>
           <xsl:call-template name="search-and-replace">
             <xsl:with-param name="input"
                   select="substring-after($input,$search-string)"/>
             <xsl:with-param name="search-string"
                   select="$search-string"/>
             <xsl:with-param name="replace-string"
                   select="$replace-string"/>
           </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$input"/>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:template>                
      <xsl:template match="text">
       <xsl:call-template name="search-and-replace">
         <xsl:with-param name="input" select="text()" />
         <xsl:with-param name="search-string" select="'&#x9;'" />
         <xsl:with-param name="replace-string" select="''" />
       </xsl:call-template>    
      </xsl:template>
    </xsl:stylesheet>
    

    XSLT 2.0 makes this trivial with the replace function:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="xs"
          version="2.0">
     <xsl:template match="text">
      <xsl:value-of select="replace(text(), '&#x9;', '')" />
     </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
  • 2020-12-02 13:51

    My previouse answer is wrong, all commas must be output via tag 'text'

    <?xml version="1.0" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
        <xsl:template match="/PHONEBOOK">
            <xsl:for-each select="LISTING">
                <xsl:value-of select="RELATION" /><xsl:text>, </xsl:text>
                <xsl:value-of select="FIRST" /><xsl:text>, </xsl:text>
                <xsl:value-of select="LAST" /><xsl:text>, </xsl:text>
    
                    <xsl:for-each select="ADDRESS">
                        <xsl:choose>
                            <xsl:when test="@TYPE">
                                <xsl:value-of select="@TYPE" /><xsl:text>,</xsl:text>
                            </xsl:when>
                            <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise>
                        </xsl:choose>
                    <xsl:value-of select="STREET/text()" /><xsl:text>,</xsl:text>
                        <xsl:value-of select="CITY/text()" /><xsl:text>,</xsl:text>
                        <xsl:value-of select="STATE/text()" /><xsl:text>,</xsl:text>
                        <xsl:value-of select="ZIP/text()" /><xsl:text>,</xsl:text>
                    </xsl:for-each>
    
                <xsl:for-each select="PHONE">
                    <xsl:choose>
                        <xsl:when test="@TYPE">
                            <xsl:value-of select="@TYPE" />  
                        </xsl:when>
                        <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise>
                    </xsl:choose>
                    <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
                </xsl:for-each>
    
                <xsl:if test="EMAIL">
                    <xsl:for-each select="EMAIL">
                        <xsl:choose>
                            <xsl:when test="@TYPE">
                                <xsl:value-of select="@TYPE" /><xsl:text  > </xsl:text> 
                            </xsl:when>
                            <xsl:otherwise><xsl:text  >Personal </xsl:text></xsl:otherwise>
                        </xsl:choose>
                        <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
                    </xsl:for-each>
                </xsl:if>
                <xsl:text>&#10;&#13;</xsl:text>
            </xsl:for-each>
        </xsl:template>
        <xsl:template match="text()|@*">
            <xsl:text>-</xsl:text>
        </xsl:template>
    
    </xsl:stylesheet>
    
    0 讨论(0)
提交回复
热议问题