【问题标题】:Using XSL to sort XML data then output an XML file to be read by Classic ASP使用 XSL 对 XML 数据进行排序,然后输出一个 XML 文件以供 Classic ASP 读取
【发布时间】:2010-07-30 11:20:42
【问题描述】:

希望这将是一个简单的修复。我对 XSL 完全陌生,但我设法获得了一个按日期对数据进行排序的小脚本。我现在想使用 ASP 将此数据限制为一个月内的所有条目(这通过使用 DateDiff() 函数来工作)。当我加载 XSL 脚本输出时,它说我的 XML 格式错误。有谁能帮帮我吗?

这是我的 XML 文件:

<?xml version="1.0"?>
<Rota>
   <Shift>
      <date>23/07/2010</date>
      <title1>GM Neurosciences</title1>
      <gm>Katie Cusick</gm>
      <title2>Chief Operating Officer</title2>
      <director>Patrick Mitchell</director>
      <nurse>n/a</nurse>
    </Shift>
    <Shift>
      <date>30/07/2010</date>
      <title1>GM Specialised Medicine</title1>
      <gm>Alison Watson</gm>
      <title2>DDO Medicine &amp; Cardio.</title2>
      <director>Suzanne Marsello</director>
      <nurse>n/a</nurse>
    </Shift>
</Rota>

这是我的 XSL 文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" omit-xml-declaration="no" version="1.0" />
   <xsl:param name="sortBy" select="'date'"/>
   <xsl:param name="strXPath" select="//Shift"/>
   <xsl:template match="/"> 
      <xsl:apply-templates select="$strXPath">
               <xsl:sort select="substring(date,7,4)"/> <!-- year sort -->
               <xsl:sort select="substring(date,4,2)"/> <!-- month sort -->  
               <xsl:sort select="substring(date,1,2)"/> <!-- day sort -->
          </xsl:apply-templates>
   </xsl:template>
   <xsl:template match="Shift"> 
       <Shift>
           <date><xsl:value-of select="date"/></date>
           <title1><xsl:value-of select="title1"/></title1>
           <gm><xsl:value-of select="gm"/><gm>
           <title2><xsl:value-of select="title2"/></title2>
           <director><xsl:value-of select="director"/></director>
           <nurse><xsl:value-of select="nurse"/></nurse>
       </Shift>
    </xsl:template>
</xsl:stylesheet>

这是我的 ASP 代码:

<%

Set entries = Server.CreateObject("Microsoft.XMLDOM")
Set entry = Server.CreateObject("Microsoft.XMLDOM")
Set xml = Server.CreateObject("Microsoft.XMLDOM")
Set xsl = Server.CreateObject("Microsoft.XMLDOM")
Set newxml = Server.CreateObject("Microsoft.XMLDOM")

xml.async = False
xml.load (Server.MapPath("rota.xml"))

xsl.async = False
xsl.load(Server.MapPath("indexrota.xsl"))
newxml.async = False
newxml.load(xml.transformNode(xsl))

set entries = newxml.getElementsbyTagName("Shift")
noOfEntries = entries.length
startDate = "15/07/2010"
LastDate = DateAdd("m",1,date())


Response.Write("<table><tr><th>Date</th><th>Title</th><th>GM</th><th>Title</th><th>Director</th><th>Nurse / Matron</th></tr>")
For i = 0 To (noOfEntries - 1)
    Set entry = entries.item(i)
    If isDate(entry.childNodes(0).text) Then
        meh = CDate(entry.childNodes(0).text)
        beginning = DateDiff("d", meh, startDate)
        ended = DateDiff("d", meh, LastDate)
        If beginning + 1 <= 0 And ended >= 0 Then
            Response.Write("<tr>"&_
            "<td>" & entry.childNodes(0).text & "</td>"&_
            "<td>" & entry.childNodes(1).text & "</td>"&_
            "<td>" & entry.childNodes(2).text & "</td>"&_
            "<td>" & entry.childNodes(3).text & "</td>"&_
            "<td>" & entry.childNodes(4).text & "</td>"&_
            "<td>" & entry.childNodes(5).text & "</td>"&_
            "</tr>")
            End If
        End If
    Next
    Response.Write("</table>")
%>

我确信这是 XSL 的一个例子,因为 ASP 之前在 XML 上工作得非常完美

【问题讨论】:

  • XSLT 和 ASP 代码实际上都存在问题。见下文!

标签: xml xslt sorting asp-classic


【解决方案1】:

您的 XSL 存在两个问题。

首先,在你复制 gm 元素的地方,你没有正确关闭 gm 标签。

<gm><xsl:value-of select="gm"/><gm> 

这应该变成

<gm><xsl:value-of select="gm"/></gm> 

其次,尽管您正在复制 Shift 元素,但生成的 XML 不包含根元素。您需要在 xsl:apply-templates 调用之外放置一个 Rota 元素

<xsl:template match="/"> 
   <Rota>  
       <xsl:apply-templates select="$strXPath">  
           <xsl:sort select="substring(date,7,4)"/> <!-- year sort -->  
           <xsl:sort select="substring(date,4,2)"/> <!-- month sort -->    
           <xsl:sort select="substring(date,1,2)"/> <!-- day sort -->  
        </xsl:apply-templates>  
    </Rota>
</xsl:template>  

请注意,您可以简化 Shift 元素的复制,只需这样做

<xsl:template match="Shift">  
   <xsl:copy-of select="." />
</xsl:template> 

ASP 代码也有问题。 newxml.load(xml.transformNode(xsl)) 行不正确。因为 transformNode 返回一个包含 XML 的字符串,所以您确实需要执行以下操作

newxml.loadXml(xml.transformNode(xsl))

从文件加载 xml 时使用 load。加载包含 Xml 的字符串时使用 loadXml

【讨论】:

  • 您好,感谢您对 XML 提出的建议,现在可以正常加载。我看到它在 Shift 上小写了 S。不过,我还有另一个问题,这次是在 ASP 方面。我使用 set entries = newxml.getElementsbyTagName("shift") noOfEntries = entries.length 将班次数输入 for 循环,然后只显示当月的班次数。当我运行 getElementsByTagName 时,它​​返回 0,即使 newxml 代码的 response.write 显示它正确输出。知道如何解决这个问题吗?谢谢。
  • 试试 newxml.documentElement.SelectNodes("Shift")
  • 我已经尝试过了,它返回错误类型:Microsoft VBScript 运行时 (0x800A01A8) 需要对象:'[object]' 我正在正确加载转换后的文档,不是吗? //EDIT// 我刚刚取出了 documentElement 部分,它没有导致错误,但仍然没有找到节点
  • 我刚刚注意到问题出在 newxml.load(xml.transformNode(xsl)) 行上。因为 transformNode 返回一个包含 XML 的字符串,所以您确实需要执行 newxml.loadXml(xml.transformNode(xsl))。从文件加载 xml 时使用 load。加载包含 Xml 的字符串时使用 loadXml
  • 这行得通,非常感谢。很抱歉周末没有回复,但这是为了工作。
【解决方案2】:

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Rota">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="substring(date,7)"/>
                <xsl:sort select="substring(date,4,2)"/>
                <xsl:sort select="substring(date,1,2)"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

有了这个输入:

<Rota>
    <Shift>
      <date>30/07/2010</date>
      <title1>GM Specialised Medicine</title1>
      <gm>Alison Watson</gm>
      <title2>DDO Medicine &amp; Cardio.</title2>
      <director>Suzanne Marsello</director>
      <nurse>n/a</nurse>
    </Shift>
   <Shift>
      <date>23/07/2010</date>
      <title1>GM Neurosciences</title1>
      <gm>Katie Cusick</gm>
      <title2>Chief Operating Officer</title2>
      <director>Patrick Mitchell</director>
      <nurse>n/a</nurse>
    </Shift>
</Rota>

输出:

<Rota>
    <Shift>
        <date>23/07/2010</date>
        <title1>GM Neurosciences</title1>
        <gm>Katie Cusick</gm>
        <title2>Chief Operating Officer</title2>
        <director>Patrick Mitchell</director>
        <nurse>n/a</nurse>
    </Shift>
    <Shift>
        <date>30/07/2010</date>
        <title1>GM Specialised Medicine</title1>
        <gm>Alison Watson</gm>
        <title2>DDO Medicine &amp; Cardio.</title2>
        <director>Suzanne Marsello</director>
        <nurse>n/a</nurse>
    </Shift>
</Rota>

此外,此样式表也有效:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="substring(date,7)"/>
                <xsl:sort select="substring(date,4,2)"/>
                <xsl:sort select="substring(date,1,2)"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

注意:正确的子字符串。我更改输入顺序,因为默认顺序是升序。如果你想要后代顺序添加到xsl:sort这个属性order="descending"

EDIT:还原了错误的子字符串。另外,为什么不使用 XSLT 做所有事情呢?例如,这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="startDate" select="20100715"/>
    <xsl:param name="endDate" select="$startDate + 100"/>
    <xsl:template match="Rota">
        <table>
            <tr>
                <th>Date</th>
                <th>Title</th>
                <th>GM</th>
                <th>Title</th>
                <th>Director</th>
                <th>Nurse / Matron</th>
            </tr>
            <xsl:apply-templates select="Shift[concat(substring(date,7),
                                                      substring(date,4,2),
                                                      substring(date,1,2))
                                               >= $startDate]
                                               [$endDate >=
                                               concat(substring(date,7),
                                                      substring(date,4,2),
                                                      substring(date,1,2))]">
                <xsl:sort select="substring(date,7)"/>
                <xsl:sort select="substring(date,4,2)"/>
                <xsl:sort select="substring(date,1,2)"/>
            </xsl:apply-templates>
        </table>
    </xsl:template>
    <xsl:template match="Shift">
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:template>
    <xsl:template match="Shift/*">
        <td>
            <xsl:value-of select="."/>
        </td>
    </xsl:template>
</xsl:stylesheet>

输出:

<table>
    <tr>
        <th>Date</th>
        <th>Title</th>
        <th>GM</th>
        <th>Title</th>
        <th>Director</th>
        <th>Nurse / Matron</th>
    </tr>
    <tr>
        <td>23/07/2010</td>
        <td>GM Neurosciences</td>
        <td>Katie Cusick</td>
        <td>Chief Operating Officer</td>
        <td>Patrick Mitchell</td>
        <td>n/a</td>
    </tr>
    <tr>
        <td>30/07/2010</td>
        <td>GM Specialised Medicine</td>
        <td>Alison Watson</td>
        <td>DDO Medicine &amp; Cardio.</td>
        <td>Suzanne Marsello</td>
        <td>n/a</td>
    </tr>
</table>

【讨论】:

  • 谢谢,我在运行 newxml.getElementByTagName("Shift") 时仍然没有得到响应。知道为什么会这样吗?
  • 感谢您的回复。我设法使用 Tim C 的解决方案完成了我需要的工作,但感谢您向我展示了如何使用 XSL
  • @Colin Wren:不客气。我不再使用经典的 ASP... 对我来说,重要的是您要注意所有工作(包括构建表格)都可以使用 XSLT 轻松完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多