How to preserve Empty XML Tags after XSLT - prevent collapsing them from to

后端 未结 10 2612
不思量自难忘°
不思量自难忘° 2020-12-18 22:31

Say I have a very simple XML with an empty tag \'B\':


  foo
  
  bar



        
相关标签:
10条回答
  • 2020-12-18 22:51

    They are NOT always equivalent. Many browsers can't deal with <script type="..." src="..." /> and want a separate closing tag. I ran into this problem while using xml/xsl with PHP. Output "html" didn't work, I'm still looking for a solution.

    0 讨论(0)
  • 2020-12-18 22:52

    Ok, so here what worked for me:

    <xsl:output method="html">
    
    0 讨论(0)
  • 2020-12-18 22:58

    This has been a long time issue and I finally made it work with a simple solution.

    Add <xsl:text/> if you have a space character. I added a space in my helper class.

    <xsl:choose>
     <xsl:when test="$textAreaValue=' '">
       <xsl:text/>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$textAreaValue"/>
     </xsl:otherwise>
    </xsl:choose>
    
    0 讨论(0)
  • 2020-12-18 22:59

    There is no standard way, as they are equivalent; You might be able to find an XSLT engine that has an option for this behaviour, but I'm not aware of any.

    If you're passing this to a third party that cannot accept empty tags using this syntax, then you may have to post-process the output yourself (or convince the third party to fix their XML parsing)

    0 讨论(0)
  • 2020-12-18 23:00

    It's 7 years late, but for future readers I will buck the trend here and propose an actual solution to the original question. A solution that does not modify the original with spaces or the output directive.

    The idea was to use an empty variable to trick the parser.

    If you only want to do it just for one tag B, my first thought was to use something like this to attach a dummy variable.

    <xsl:variable name="dummyempty" select="''"/>
    
    <xsl:template match="B">    
      <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:value-of select="concat(., $dummyempty)"/>
      </xsl:copy>    
    </xsl:template>
    

    But I found that in fact, even the dummy variable is not necessary. This preserved empty tags, at least when tested with xsltproc in linux :

    <xsl:template match="B">
      <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:value-of select="."/>
      </xsl:copy>    
    </xsl:template>
    

    For a more generic solution to handle ALL empty tags, try this:

      <xsl:variable name="dummyempty" select="''"/>
    
      <xsl:template match="*[. = '']">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
            <xsl:value-of select="$dummyempty"/>
        </xsl:copy>
      </xsl:template>
    

    Again, depending on how smart your parser is, you may not even need the dummy variable.

    0 讨论(0)
  • 2020-12-18 23:01

    It is up to the XSLT engine to decide how the XML tag is rendered, because a parser should see no difference between the two variations. However, when outputting HTML this is a common problem (for <textarea> and <script> tags for example.) The simplest (but ugly) solution is to add a single whitespace inside the tag (this does change the meaning of the tag slightly though.)

    0 讨论(0)
提交回复
热议问题