Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 基于输入XML中的复杂元素将XML转换为HTML_Xslt_Xslt 2.0 - Fatal编程技术网

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

Xslt 基于输入XML中的复杂元素将XML转换为HTML,xslt,xslt-2.0,Xslt,Xslt 2.0,我是XSLT新手,我正在尝试将下面xml中的数据解析为html,其中每个根/引号/引号都是一个载体,载体的值根据各自引号中的QuoteId确定,我需要根据QuoteId并排显示Quote-1和Quote-2的对应值,其中QuoteId位于1st和2nd下,我需要显示所有根/引号/引号中的所有不同元素及其值,或者如果元素或元素值中的任何一个不存在-我需要显示“未找到” 第一个可能有根/Quotes/Quote's和的1、2、3和第二个可能有的1和3,在这种情况下,我需要将Quote-2的所有标签值

我是XSLT新手,我正在尝试将下面xml中的数据解析为html,其中每个根/引号/引号都是一个载体,载体的值根据各自引号中的QuoteId确定,我需要根据QuoteId并排显示Quote-1和Quote-2的对应值,其中QuoteId位于1st
和2nd
下,我需要显示所有根/引号/引号中的所有不同元素及其值,或者如果元素或元素值中的任何一个不存在-我需要显示“未找到”

第一个
可能有根/Quotes/Quote's和
的1、2、3和第二个
可能有
的1和3,在这种情况下,我需要将Quote-2的所有标签值显示为“未找到”

输入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>

报价-1
报价-2
所需输出


类型
车辆
标签
报价-1
报价-2
发动机
车辆1
要素1
122
233
元素2
233
找不到
元素3
344
找不到
元素4
455
找不到
报价单
1.
1.
要素7
找不到
找不到
要素8
找不到
找不到
元素10
找不到
找不到
元素11
找不到
找不到
要素12
找不到
123
元素13
找不到
找不到
元素14
找不到
找不到
元素15
找不到
找不到
元素16
找不到
找不到
发动机
车辆2
要素1
466
找不到
元素2
577
找不到
元素3
找不到
找不到
元素4
找不到
找不到
报价单
2.
2.
要素7
688
找不到
要素8
799
找不到
元素10
找不到
找不到
元素11
找不到
找不到
要素12
找不到
找不到
元素13
找不到
133
元素14
找不到
234
元素15
找不到
456
元素16
找不到
654
发动机
车辆3
要素1
找不到
找不到
元素2
找不到
找不到
元素3
找不到
找不到
元素4
找不到
找不到
报价单
找不到
找不到
要素7
找不到
找不到
要素8
找不到
找不到
元素10
找不到
找不到
元素11
找不到
找不到
要素12
找不到
找不到
元素13
找不到
234
元素14
找不到
443
元素15
找不到
654
元素16
找不到
544

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

要管理这一点,您需要一个所有可能元素名称的列表以及
的最大数量

然后,您可以通过
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 &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>

类型
车辆
标签
1.
发动机
车辆
找不到

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

要管理这一点,您需要一个所有可能元素名称的列表以及
的最大数量

然后