首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于输入XML中的复杂元素将xml转换为HTML

基于输入XML中的复杂元素将xml转换为HTML
EN

Stack Overflow用户
提问于 2016-01-03 16:17:38
回答 1查看 75关注 0票数 1

我是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

代码语言:javascript
复制
<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>

期望输出

代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

发布于 2016-01-04 14:44:32

您正在将输入中的行转换为输出中的列,并且正在寻找不可能包含在每个<Quote>中的元素。

要管理这一点,您需要列出所有可能的元素名称和<Quotes>的最大数量。

然后,您可以通过Quotes循环position()列表,并从$elements列表中查找所有元素。

完整解决方案:

代码语言:javascript
复制
<?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 &lt; $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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34578685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档