使用XSLT在XML文档中将数据从一个节点添加到另一个节点

时间:2018-06-26 15:54:25

标签: xslt

我有一个XML文档,其中包含两组数据。我需要输出一个包含数据的HTML表。

XML看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<fdata>
    <RepairHistory>
        <RepairList>
            <RepairJob>
                <RepairRef>56740408</RepairRef>
                <RepairDescription>Baths</RepairDescription>
                <RepairReportedDate>20180515</RepairReportedDate>
                <RepairCompletedDate></RepairCompletedDate>
                <RepairStartDate>20180515</RepairStartDate>
            </RepairJob>
            <RepairJob>
                <RepairRef>56735043</RepairRef>
                <RepairDescription>Basins</RepairDescription>
                <RepairReportedDate>20180515</RepairReportedDate>
                <RepairCompletedDate></RepairCompletedDate>
                <RepairStartDate>20180515</RepairStartDate>
            </RepairJob>
            <RepairJob>
                <RepairRef>56740415</RepairRef>
                <RepairDescription>Showers</RepairDescription>
                <RepairReportedDate>20180515</RepairReportedDate>
                <RepairCompletedDate></RepairCompletedDate>
                <RepairStartDate>20180515</RepairStartDate>
            </RepairJob>
        </RepairList>
    </RepairHistory>
    <map>
        <entry>
            <string>GUID</string>
            <string>be0f53f5-7a09-47cd-9928-0c865b6450a5</string>
        </entry>
        <entry>
            <string>JOBNUMBER</string>
            <string>56740408</string>
        </entry>
    </map>
    <map>
        <entry>
            <string>GUID</string>
            <string>5ce2e8fe-7735-4f98-b3a9-3bd386edb338</string>
        </entry>
        <entry>
            <string>JOBNUMBER</string>
            <string>56740415</string>
        </entry>
    </map>
</fdata>

JOBNUMBER必须匹配RepairRef。并非底部的所有数据都与顶部的数据匹配。 我需要将数据输出到表中,如下所示:

Date       Ref        Details    GUID
20180515   56740408   Baths      be0f53f5-7a09-47cd-9928-0c865b6450a5
20180515   56735043   Basins     No GUID
20180515   56740415   Showers    5ce2e8fe-7735-4f98-b3a9-3bd386edb338

我尝试使用以下xsl输出表,但是它不起作用...

<xsl:template match="/">
    <h3>Repair history</h3>
    <table>
        <tr>
            <th>Date</th>
            <th>Ref</th>
            <th>Details</th>
            <th>GUID</th>
        </tr>               
        <xsl:apply-templates select ="//RepairJob" />
    </table>
</xsl:template>
<xsl:template match="RepairJob">
    <xsl:variable name="JobNumber" select="RepairRef" />
     <tr>
         <td><xsl:value-of select="RepairStartDate"/></td>
         <td><xsl:value-of select="RepairRef"/></td>
         <td><xsl:value-of select="RepairDescription"/></td>
         <td>
            <xsl:choose>
                <xsl:when test="count(//map//entry[2]//string[2] = $JobNumber) &gt; 0">
                     <xsl:value-of select="//map//entry[2]//string[2] = $JobNumber"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>No GUID</xsl:text>
                </xsl:otherwise>
            </xsl:choose>                
        </td>
     </tr>
</xsl:template>

我可以看到我没有选择要显示的正确节点,但是匹配也不起作用。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您当前的xsl:value-of的值为布尔值(“ true”或“ false”)。您真正想要的表达式是这个...

<xsl:value-of select="//map[entry[2]/string[2] = $JobNumber]/entry[1]/string[2]"/>

xsl:when也需要进行调整,因此整个xsl:choose应该看起来像这样:

<xsl:choose>
    <xsl:when test="//map[entry[2]/string[2] = $JobNumber]">
         <xsl:value-of select="//map[entry[2]/string[2] = $JobNumber]/entry[1]/string[2]"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>No GUID</xsl:text>
    </xsl:otherwise>
</xsl:choose>    

但是,请考虑使用按键来查找向导。...

<xsl:key name="map" match="map" use="entry[string[1] = 'JOBNUMBER']/string[2]" />

然后您的xsl:value-of变成这个

<xsl:value-of select="key('map',$JobNumber)/entry[string[1] = 'GUID']/string[2]"/>

注意,这还允许entry元素内的map元素以任意顺序排列(即JOBNUMBER可以是第一个条目,GUID可以是第二个条目)

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="html" indent="yes" />

<xsl:key name="map" match="map" use="entry[string[1] = 'JOBNUMBER']/string[2]" />

<xsl:template match="/">
    <h3>Repair history</h3>
    <table>
        <tr>
            <th>Date</th>
            <th>Ref</th>
            <th>Details</th>
            <th>GUID</th>
        </tr>               
        <xsl:apply-templates select ="//RepairJob" />
    </table>
</xsl:template>

<xsl:template match="RepairJob">
    <xsl:variable name="JobNumber" select="RepairRef" />
     <tr>
         <td><xsl:value-of select="RepairStartDate"/></td>
         <td><xsl:value-of select="RepairRef"/></td>
         <td><xsl:value-of select="RepairDescription"/></td>
         <td>
            <xsl:choose>
                <xsl:when test="key('map',$JobNumber)">
                     <xsl:value-of select="key('map',$JobNumber)/entry[string[1] = 'GUID']/string[2]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>No GUID</xsl:text>
                </xsl:otherwise>
            </xsl:choose>                
        </td>
     </tr>
</xsl:template>
</xsl:stylesheet>