我是XSLT的新手,我试图解析xml到html下面的数据,其中每个根/引号/引号都是一个载体,在相应的引号中基于QuoteID确定了Vehicle的值,我需要在1 <Sequence>和2 <Sequence>下同时显示Quote-1和Quote-2的对应值,基于QuoteID,我需要显示所有根/引号中所有不同的元素,或者如果元素或元素的任何值不存在,我需要显示“not”。
第一个<Sequence>可能有根/引号/引号,<SequenceID>的1、2、3和2 <Sequence>可以有<SequenceID>的1和3,在这种情况下,我需要将Quote-2的所有标签值显示为“Not”。
输入XML
<HTMLData>
<Sequence>
<QuoteTitle>Quote-1</QuoteTitle>
<Response>
<root>
<Quotes>
<Quote>
<Element1 value="122"/>
<Element2 value="233"/>
<Element3 value="344"/>
<Element4 value="455"/>
<QuoteID value="1"/>
</Quote>
</Quotes>
<Quotes>
<Quote>
<Element1 value="466"/>
<Element2 value="577"/>
<Element7 value="688"/>
<Element8 value="799"/>
<QuoteID value="2"/>
</Quote>
</Quotes>
</root>
</Response>
</Sequence>
<Sequence>
<QuoteTitle>Quote-2</QuoteTitle>
<Response>
<root>
<Quotes>
<Quote>
<Element1 value="233"/>
<Element10 value=""/>
<Element11 value=""/>
<Element12 value="123"/>
<QuoteID value="1"/>
</Quote>
</Quotes>
<Quotes>
<Quote>
<Element13 value="123"/>
<Element14 value="234"/>
<Element15 value="456"/>
<QuoteID value="2"/>
<Element16 value="654"/>
</Quote>
</Quotes>
<Quotes>
<Quote>
<Element13 value="234"/>
<Element14 value="443"/>
<Element15 value="654"/>
<Element16 value="544"/>
<QuoteID value="3"/>
</Quote>
</Quotes>
</root>
</Response>
</Sequence>
</HTMLData>期望输出
<table xmlns:xs="http://www.w3.org/2001/XMLSchema" border="1">
<tr>
<th class="border-top border-bottom border-left border-right">Type</th>
<th class="border-top border-bottom border-left border-right">Vehicle</th>
<th class="border-top border-bottom border-left border-right">Label</th>
<th class="border-top border-bottom border-left border-right">Quote-1</th>
<th class="border-top border-bottom border-left border-right">Quote-2</th>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right">Motor</td>
<td class="border-top border-bottom border-left border-right">Vehicle1</td>
<td class="border-top border-bottom border-left border-right">Element1</td>
<td class="border-top border-bottom border-left border-right">122</td>
<td class="border-top border-bottom border-left border-right">233</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element2</td>
<td class="border-top border-bottom border-left border-right">233</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element3</td>
<td class="border-top border-bottom border-left border-right">344</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element4</td>
<td class="border-top border-bottom border-left border-right">455</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">QuoteID</td>
<td class="border-top border-bottom border-left border-right">1</td>
<td class="border-top border-bottom border-left border-right">1</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element7</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element8</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element10</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element11</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element12</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">123</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element13</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element14</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element15</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element16</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right" colspan="count()">Motor</td>
<td class="border-top border-bottom border-left border-right">Vehicle2</td>
<td class="border-top border-bottom border-left border-right">Element1</td>
<td class="border-top border-bottom border-left border-right">466</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element2</td>
<td class="border-top border-bottom border-left border-right">577</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element3</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element4</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">QuoteID</td>
<td class="border-top border-bottom border-left border-right">2</td>
<td class="border-top border-bottom border-left border-right">2</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element7</td>
<td class="border-top border-bottom border-left border-right">688</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element8</td>
<td class="border-top border-bottom border-left border-right">799</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element10</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element11</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element12</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element13</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">133</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element14</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">234</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element15</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">456</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element16</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">654</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right" colspan="count()">Motor</td>
<td class="border-top border-bottom border-left border-right">Vehicle3</td>
<td class="border-top border-bottom border-left border-right">Element1</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element2</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element3</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element4</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">QuoteID</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element7</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element8</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element10</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element11</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element12</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element13</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">234</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element14</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">443</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element15</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">654</td>
</tr>
<tr>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right">Element16</td>
<td class="border-top border-bottom border-left border-right">Not Found</td>
<td class="border-top border-bottom border-left border-right">544</td>
</tr>
</table>
发布于 2016-01-04 14:44:32
您正在将输入中的行转换为输出中的列,并且正在寻找不可能包含在每个<Quote>中的元素。
要管理这一点,您需要列出所有可能的元素名称和<Quotes>的最大数量。
然后,您可以通过Quotes循环position()列表,并从$elements列表中查找所有元素。
完整解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"
version="1.0">
<xsl:output method="html"/>
<xsl:key name="element-key" match="//root/Quotes/Quote/*" use="name()" />
<!-- collect all posible element-names -->
<xsl:variable name="elements">
<xsl:for-each select="//root/Quotes/Quote/*">
<xsl:if test="generate-id() = generate-id(key('element-key', name())[1])">
<xsl:apply-templates mode="elements" select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="Quote/*" mode="elements">
<element>
<xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
</element>
</xsl:template>
<xsl:variable name="vehicleCount">
<xsl:call-template name="vehicleCount">
<xsl:with-param name="nodelist" select="//root"></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:template name="vehicleCount">
<xsl:param name="nodelist" />
<xsl:choose>
<xsl:when test="count($nodelist) > 0">
<xsl:variable name="countFirst" select="count(exsl:node-set($nodelist[1])/Quotes)"/>
<xsl:variable name="maxRest">
<xsl:call-template name="vehicleCount">
<xsl:with-param name="nodelist" select="exsl:node-set($nodelist[position()>1])" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$countFirst > $maxRest"><xsl:value-of select="$countFirst"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$maxRest"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:variable name="quoteTitles">
<xsl:copy-of select="/HTMLData/Sequence/QuoteTitle"/>
</xsl:variable>
<xsl:variable name="sequences">
<xsl:copy-of select="/HTMLData/Sequence"/>
</xsl:variable>
<xsl:template match="/">
<table>
<tr>
<th class="border-top border-bottom border-left border-right">Type</th>
<th class="border-top border-bottom border-left border-right">Vehicle</th>
<th class="border-top border-bottom border-left border-right">Label</th>
<xsl:for-each select="exsl:node-set($quoteTitles)/*">
<th class="border-top border-bottom border-left border-right"><xsl:value-of select="text()"/></th>
</xsl:for-each>
</tr>
<xsl:call-template name="outputVehicle"/>
</table>
</xsl:template>
<xsl:template name="outputVehicle">
<xsl:param name="pos">1</xsl:param>
<xsl:for-each select="exsl:node-set($elements)/*">
<xsl:variable name="elementName" select="@name"/>
<tr>
<xsl:choose>
<xsl:when test="$elementName = exsl:node-set($elements)/*[1]/@name">
<td class="border-top border-bottom border-left border-right">Motor</td>
<td class="border-top border-bottom border-left border-right">Vehicle<xsl:value-of select="$pos"/></td>
</xsl:when>
<xsl:otherwise>
<td class="border-top border-bottom border-left border-right"></td>
<td class="border-top border-bottom border-left border-right"></td>
</xsl:otherwise>
</xsl:choose>
<td class="border-top border-bottom border-left border-right"><xsl:value-of select="$elementName"/></td>
<xsl:for-each select="exsl:node-set($quoteTitles)/*">
<xsl:variable name="quoteTitle" select="text()"/>
<xsl:variable name="quote" select="exsl:node-set($sequences)/*[QuoteTitle=$quoteTitle]/Response/root/Quotes[position()=$pos]/Quote/*[name()=$elementName]/@value" />
<td class="border-top border-bottom border-left border-right">
<xsl:choose>
<xsl:when test="$quote"><xsl:value-of select="$quote"/></xsl:when>
<xsl:otherwise>Not Found</xsl:otherwise>
</xsl:choose>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
<xsl:if test="$pos < $vehicleCount">
<!-- wonder if xslt-processors are able to do tail-call optimization... -->
<xsl:call-template name="outputVehicle"><xsl:with-param name="pos" select="$pos+1" /></xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/34578685
复制相似问题