在XSLT中从XML文件中缩写序列号

时间:2015-07-13 13:07:58

标签: xml parsing xslt formatting

这可能相当简单,但我是XSLT的新手,在尝试找到缩短必须在表格中显示的序列号长度的方法时遇到了麻烦。我有一个XML文件,其中包含有关许多电表读数的带时间戳的数据。我的目标是从XML文件中获取仪表数据并将其转换为可通过样式表在Internet Explorer中轻松查看的表格。我正确设置了解析和表格,所以我现在正在处理一些小事来清理表格。

每个仪表都在XML文件中以电子序列号(ESN)命名。 ESN是22格式的唯一标识符,格式为 3.54.765.2.233245.4.64352456 ESN中唯一需要在表格中显示的部分是最后8位数(在此示例中为 64352456 )。

我已经尝试使用 format-number()命令进行各种操作,但是这个序列号似乎有问题,因为它不是实数。在我的样式表中,我正在检索并将ESN存储为变量“ESN”,并在稍后的表格中将其显示为完整的ESN,我们非常感谢有关如何将MeterID缩短到最后8位的任何想法!这是我的样式表,我不认为我可以发布XML,因为公司隐私的东西。谢谢!

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:local="#local-functions"
    xmlns:dt="urn:schemas-microsoft-com:datatypes"

    xmlns="http://www.w3.org/TR/REC-html40" 
                      xmlns:itron="http://schemas.datacontract.org/2004/07/Itron.Ami.AmiServiceTest.Hosting"
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:d2p1="http://www.itron.com/ami/2008/10/data"
    xmlns:d3p1="http://www.itron.com/ami/2008/10/common"
    xmlns:d5p1="http://www.itron.com/ami/2008/10/events"
    xmlns:d7p1="http://www.w3.org/2001/XMLSchema">

<xsl:template match="/">
<!--        Print Title     -->
    <div>AMI DATA</div>
<!--        Create Table and column headings        -->
    <table border="1" cellpadding="0" cellspacing="0">
            <tr style="background-color:#C0C0C0; font-weight:bold">

                <td>Meter ID</td>
                <td>Vh(a)</td>
                <td>Max V(a)</td>
                <td>Min V(a)</td>
                <td>Vh(c)</td>
                <td>Max V(c)</td>
                <td>Min V(c)</td>
                <td>Timestamp</td>
            </tr>
<!--        Loop through each DataSubscriberItem (each a seperate meter)   create  variables to store TimeDataEnd, PulseMultiplier, and Meter Identifier           -->
    <xsl:for-each select="XMLRoot/itron:DataSubscriberItem">
        <div>
            <xsl:variable name="EndTime" select="itron:DataArrivedInput/d2p1:ReadDataCollection/d2p1:ReadData/d2p1:LoadProfileChannels/d2p1:LoadProfileChannel/d2p1:TimeDataEnd"/>
        </div>
        <div>
            <xsl:variable name="PulsMult"   select="itron:DataArrivedInput/d2p1:ReadDataCollection/d2p1:ReadData/d2p1:LoadPr ofileChannels/d2p1:LoadProfileChannel/d2p1:PulseMultiplier"/>
        </div>
        <div>
            <xsl:variable name="ESN" select="itron:DataArrivedInput/d2p1:ReadDataCollection/d2p1:ReadData/d2p1:Identifier"/>
        </div>
<!--        Variable to keep count of entries within each DataSubscriberItem.
    It's later used to assign timestamps based on TimeDataEnd       -->         
            <xsl:variable name="NumPnts" select="count(itron:DataArrivedInput/d2p1:ReadDataCollection/d2p1:ReadData/d2p1:LoadProfileChannels/d2p1:LoadProfileChannel[1]/d2p1:IntervalValues/d2p1:IntervalValue)"/>
            <xsl:for-each   select="itron:DataArrivedInput/d2p1:ReadDataCollection/d2p1:ReadData/d2p1:LoadProfileChannels/d2p1:LoadProfileChannel[1]/d2p1:IntervalValues/d2p1:IntervalValue">
                <xsl:variable name="INum" select="position()"/>
                <xsl:variable name="EndTime2" select="../../d2p1:TimeDataEnd"/>
<!--        Start filling in table with true Voltage and Vh values      -->                 
                <tr>
                    <td>
                        <xsl:value-of select="$ESN"/>
                    </td>
                    <xsl:variable name="Vha" select="d2p1:ChannelValue"/>
                    <td>                    
                        <xsl:value-of select='format-number($Vha*$PulsMult,"0.###")'/>
                    </td>
                    <xsl:variable name="Vmaxa" select="../../../d2p1:LoadProfileChannel[2]/d2p1:IntervalValues/d2p1:IntervalValue[$INum]/d2p1:ChannelValue"/>
                    <td>
                        <xsl:value-of select='format-number($Vmaxa*$PulsMult,"0.###")'/>
                    </td>
                    <xsl:variable name="Vmina" select="../../../d2p1:LoadProfileChannel[3]/d2p1:IntervalValues/d2p1:IntervalValue[$INum]/d2p1:ChannelValue"/>
                    <td>
                        <xsl:value-of select='format-number($Vmina*$PulsMult,"0.###")'/>
                    </td>
                    <xsl:variable name="Vhc" select="../../../d2p1:LoadProfileChannel[4]/d2p1:IntervalValues/d2p1:IntervalValue[$INum]/d2p1:ChannelValue"/>
                    <td>
                        <xsl:value-of select='format-number($Vhc*$PulsMult,"0.###")'/>
                    </td>
                    <xsl:variable name="Vmaxc" select="../../../d2p1:LoadProfileChannel[5]/d2p1:IntervalValues/d2p1:IntervalValue[$INum]/d2p1:ChannelValue"/>
                    <td>
                        <xsl:value-of select='format-number($Vmaxc*$PulsMult,"0.###")'/>
                    </td>
                    <xsl:variable name="Vminc" select="../../../d2p1:LoadProfileChannel[6]/d2p1:IntervalValues/d2p1:IntervalValue[$INum]/d2p1:ChannelValue"/>
                    <td>
                        <xsl:value-of select='format-number($Vminc*$PulsMult,"0.###")'/>
                    </td>
                    <td>
                        <xsl:variable name="SDTS" select="concat(substring($EndTime2, 1,10), ' ', substring($EndTime2, 12,5))"/>
                        <xsl:value-of select="local:timeCalc($SDTS, $INum, $NumPnts)"/>
                    </td>
                </tr>

            </xsl:for-each>
    </xsl:for-each>
    </table>


</xsl:template>
<!--        VBScript to create seperate timestamps from INum variable and  TimeDataEnd      -->
<msxsl:script language="VBScript" implements-prefix="local">
        <![CDATA[
    Function timeCalc(ET, PT, TP) 
        SDT1 = CDate(ET)
        SDT = DateAdd("n", -(TP-PT)*5, SDT1)
        TTR =  PadOut(Month(SDT)) & "/" & PadOut(Day(SDT)) & "/" & Year(SDT)& " " & PadOut(Hour(SDT)-4) & ":" & PadOut(Minute(SDT))
        timeCalc =   TTR
    End Function

    Function PadOut(n)
        If n < 10 Then
            PadOut = "0" & n
        Else
            PadOut = n
        End If

    End Function
]]>
    </msxsl:script>

1 个答案:

答案 0 :(得分:0)

  

我已尝试使用 format-number()命令进行各种操作,但似乎此序列号存在问题,因为它不是一个问题。   实数。

不,这不是一个数字 - 它是一个字符串。要显示字符串的最后8个字符,可以使用:

<xsl:value-of select="substring($ESN, string-length($ESN) - 7)"/>