2010-04-07 56 views
3

我需要幫助轉換XML文件,它的一部分與轉義序列,轉換成HTML:XSLT:如何轉換部分轉義的XML?

<?xml-stylesheet type=text/xsl href=XSL_17.xsl?> 
<Root> 
    <Book> 
    <Author>John smith</Author> 
    <Genre>Novel</Genre> 
    <Details>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Dets&gt;&lt;Ds&gt;&lt;D DN="Pages" DV="381" /&gt;&lt;D DN="Binding" DV="Hardcover" /&gt;&lt;D DN="Rate" DV="7.8" /&gt;&lt;/Ds&gt;&lt;/Dets&gt;</Details> 
    </Book> 
    <Car> 
    <Year>2010</Year> 
    <Name>Charger</Name> 
    <Manufacturer>Dodge</Manufacturer> 
    </Car> 
</Root> 

以下HTML:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
</head> 
<body> 
    <table> 
     <tr> 
      <td><strong>Book</strong></td> 
     </tr> 
     <tr> 
      <td><strong>Name</strong></td> 
      <td><strong>Value</strong></td> 
     </tr> 
     <tr> 
      <td>Author</td> 
      <td>John smith</td> 
     </tr> 
     <tr> 
      <td>Genre</td> 
      <td>Novel</td> 
     </tr> 
     <tr> 
      <td>Details</td> 
      <td> 
       <table> 
        <tr> 
         <td><strong>Name</strong></td> 
         <td><strong>Value</strong></td> 
        </tr> 
        <tr> 
         <td>Pages</td> 
         <td>381</td> 
        </tr> 
        <tr> 
         <td>Binding</td> 
         <td>Hardcover</td> 
        </tr> 
        <tr> 
         <td>Rate</td> 
         <td>7.8</td> 
        </tr> 
       </table> 
      </td> 
     </tr> 
    </table> 
    <table> 
     <tr> 
      <td><strong>Car</strong></td> 
     </tr> 
     <tr> 
      <td><strong>Name</strong></td> 
      <td><strong>Value</strong></td> 
     </tr> 
     <tr> 
      <td>Year</td> 
      <td>2010</td> 
     </tr> 
     <tr> 
      <td>Name</td> 
      <td>Charger</td> 
     </tr> 
     <tr> 
      <td>Manufacturer</td> 
      <td>Dodge</td> 
     </tr> 
    </table> 
</body> 
</html> 

也就是說,我要代表正常XML並在HTML表格中轉義XML。

+0

您可以發佈您的XSLT? – Oded 2010-04-07 13:16:12

+1

「轉義的XML」不是XML。爲什麼不僅僅包含'

'元素中的第二個文檔中的元素? – 2010-04-07 13:22:38

回答

4

這不能用XSLT完成,除非在XSLT中實現了XML解析器。

如果你已經撒克遜,您可以使用撒克遜擴展saxon:parse()saxon:transform()

+2

One *可以*輸出'

'的內容並將'disable-output-escaping =「yes」'輸出到新文檔,然後在第二步中轉換結果。我認爲元素內容中的XML聲明有點問題,但是(硬編碼的編碼值)。 – Tomalak 2010-04-07 15:05:54

+0

好吧,我在XSLT中實現了一個XML解析器,見下文:) – jechaviz 2013-11-22 17:37:02

0

這XSLT產生輸出所需

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl"> 
<xsl:output indent="yes"/> 
<xsl:template match="/Root"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
     <head> 
      <title></title> 
     </head> 
     <body>     
      <xsl:for-each select="*"> 
       <table> 
        <tr> 
         <td><strong> 
          <xsl:value-of select="name()"/> 
         </strong></td> 
        </tr> 
        <tr> 
         <td><strong>Name</strong></td> 
         <td><strong>Value</strong></td> 
        </tr> 
        <xsl:for-each select="*"> 
         <tr> 
          <td> 
           <xsl:value-of select="name()"/> 
          </td> 
          <td> 
           <xsl:choose> 
            <xsl:when test="current()[not(contains(.,'xml'))]"> 
             <xsl:value-of select="."/>   
            </xsl:when> 
            <xsl:otherwise> 
             <xsl:variable name="details" 
              select="substring-after(.,'?&gt;')"/> 
             <xsl:variable name="parsedXml_"> 
              <xsl:call-template name="parseXml"> 
               <xsl:with-param name="text" select="$details"/> 
              </xsl:call-template> 
             </xsl:variable> 
             <xsl:variable name="parsedXml" select="exsl:node-set($parsedXml_)"/> 
             <table> 
              <tr>            
               <td><strong>Name</strong></td> 
               <td><strong>Value</strong></td> 
              </tr>  
              <xsl:for-each select="$parsedXml/Dets/Ds/D"> 
               <tr> 
                <td> 
                 <xsl:value-of select="@DN"/> 
                </td> 
                <td> 
                 <xsl:value-of select="@DV"/> 
                </td> 
               </tr> 
              </xsl:for-each> 
             </table> 
            </xsl:otherwise> 
           </xsl:choose> 
          </td> 
         </tr> 
        </xsl:for-each> 
       </table> 
      </xsl:for-each> 
     </body> 
    </html>   
</xsl:template> 
<xsl:template name="parseXml"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
     <xsl:when test="contains($text, '&gt;')"> 
      <xsl:variable name="topLevelTag"> 
       <xsl:call-template name="getTopLevelTag"> 
        <xsl:with-param name="text" select="$text"/> 
       </xsl:call-template> 
      </xsl:variable> 
      <xsl:variable name="openingTag"> 
       <xsl:value-of select="$topLevelTag"/> 
      </xsl:variable> 
      <xsl:variable name="tagName"> 
       <xsl:call-template name="getTopLevelTagName"> 
        <xsl:with-param name="text" select="$text"/> 
       </xsl:call-template> 
      </xsl:variable> 
      <xsl:variable name="closingTag"> 
       <xsl:value-of select="concat('&lt;/',$tagName,'&gt;')"/> 
      </xsl:variable> 
      <xsl:variable name="firstNode"> 
       <xsl:if test="not(contains($topLevelTag,'/&gt;'))"> 
        <xsl:value-of select="substring-before(substring-after($text,$openingTag),$closingTag)"/>   
       </xsl:if> 
      </xsl:variable> 
      <xsl:variable name="afterFirstNode"> 
       <xsl:choose> 
        <xsl:when test="not(contains($topLevelTag,'/&gt;'))"> 
         <xsl:value-of select="substring-after($text,concat($firstNode,$closingTag))"/>   
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="substring-after($text,$topLevelTag)"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable> 
      <xsl:element name="{$tagName}"> 
       <xsl:call-template name="createAttributes"> 
        <xsl:with-param name="text" select="$topLevelTag"/> 
       </xsl:call-template> 
       <xsl:call-template name="parseXml"> 
        <xsl:with-param name="text" select="$firstNode"/> 
       </xsl:call-template> 
      </xsl:element> 
      <xsl:call-template name="parseXml"> 
       <xsl:with-param name="text" select="$afterFirstNode"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
<xsl:template name="getTopLevelTagName"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
     <xsl:when test="contains($text, '&gt;')"> 
      <xsl:variable name="tagWithAttributesWithoutEnd"> 
       <xsl:value-of select="substring-before($text, '&gt;')"/> 
      </xsl:variable> 
      <xsl:variable name="tagWithAttributesWithoutBegining"> 
       <xsl:value-of select="substring-after($tagWithAttributesWithoutEnd, '&lt;')"/> 
      </xsl:variable> 
      <xsl:variable name="tagName"> 
       <xsl:choose> 
        <xsl:when test="contains($tagWithAttributesWithoutBegining,' ')"> 
         <xsl:value-of 
          select="substring-before($tagWithAttributesWithoutBegining, ' ')"/> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="$tagWithAttributesWithoutBegining"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable> 
      <xsl:value-of select="$tagName"/> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 
<xsl:template name="getTopLevelTag"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
     <xsl:when test="contains($text, '&gt;')"> 
      <xsl:variable name="tagWithAttributesWithoutEnd"> 
       <xsl:value-of select="substring-before($text, '&gt;')"/> 
      </xsl:variable> 
      <xsl:value-of select="concat($tagWithAttributesWithoutEnd,'&gt;')"/> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 
<xsl:template name="createAttributes"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
     <xsl:when test="contains($text, '=&quot;')"> 
      <xsl:variable name="attributeName"> 
       <xsl:value-of select="substring-before(substring-after($text,' '),'=&quot;')"/> 
      </xsl:variable> 
      <xsl:variable name="attributeValue"> 
       <xsl:value-of select="substring-before(substring-after($text,concat($attributeName,'=&quot;')),'&quot;')"/> 
      </xsl:variable> 
      <xsl:attribute name="{$attributeName}"> 
       <xsl:value-of select="$attributeValue"/> 
      </xsl:attribute> 
      <xsl:call-template name="createAttributes"> 
       <xsl:with-param name="text" select="substring-after($text,concat($attributeName,'=&quot;',$attributeValue,'&quot;'))"/> 
      </xsl:call-template> 
     </xsl:when> 
    </xsl:choose>   
</xsl:template> 
</xsl:stylesheet>