[英]XSLT: How to transform partially escaped XML with XSLT 1.0 and XALAN processor?
[英]XSLT: How to transform partially escaped XML?
我需要幫助將XML文件(其中一部分是轉義序列)轉換為HTML:
<?xml-stylesheet type=text/xsl href=XSL_17.xsl?>
<Root>
<Book>
<Author>John smith</Author>
<Genre>Novel</Genre>
<Details><?xml version="1.0" encoding="utf-16"?><Dets><Ds><D DN="Pages" DV="381" /><D DN="Binding" DV="Hardcover" /><D DN="Rate" DV="7.8" /></Ds></Dets></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>
即,我需要在HTML表格中表示普通XML和轉義XML。
除非在XSLT中實現XML解析器,否則無法使用XSLT完成此操作 。
如果你有Saxon,你可以使用Saxon擴展saxon:parse()
和saxon:transform()
該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(.,'?>')"/>
<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, '>')">
<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('</',$tagName,'>')"/>
</xsl:variable>
<xsl:variable name="firstNode">
<xsl:if test="not(contains($topLevelTag,'/>'))">
<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,'/>'))">
<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, '>')">
<xsl:variable name="tagWithAttributesWithoutEnd">
<xsl:value-of select="substring-before($text, '>')"/>
</xsl:variable>
<xsl:variable name="tagWithAttributesWithoutBegining">
<xsl:value-of select="substring-after($tagWithAttributesWithoutEnd, '<')"/>
</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, '>')">
<xsl:variable name="tagWithAttributesWithoutEnd">
<xsl:value-of select="substring-before($text, '>')"/>
</xsl:variable>
<xsl:value-of select="concat($tagWithAttributesWithoutEnd,'>')"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="createAttributes">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, '="')">
<xsl:variable name="attributeName">
<xsl:value-of select="substring-before(substring-after($text,' '),'="')"/>
</xsl:variable>
<xsl:variable name="attributeValue">
<xsl:value-of select="substring-before(substring-after($text,concat($attributeName,'="')),'"')"/>
</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,'="',$attributeValue,'"'))"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.