【问题标题】:Avoid reloading all XML data for each repeater - vb.net避免为每个转发器重新加载所有 XML 数据 - vb.net
【发布时间】:2011-06-15 17:52:41
【问题描述】:

我正在尝试使用 xml 数据在中继器中放置中继器。我让它完全按照我的意愿工作,但是我使用的方法会重新加载每个中继器的数据。我想我需要转换为 XmlNode,但老实说 - 我不知道从哪里开始。

这是我的代码 - 如果可能,我想将所有内容都保留在代码中。

<script runat="server">

Public doc As New XmlDocument()

Public Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)

    If Not Page.IsPostBack then

        doc.Load(Server.MapPath("~/myxml/bookstore.xml"))

        Dim nodes As XmlNodeList = doc.SelectNodes("Bookings/Booking[@CLIENT_NO='SA33762']")
        rpMyRepeater.DataSource = nodes
        rpMyRepeater.DataBind()

    End If

End Sub

   Protected Sub itemDB(ByVal s As Object, ByVal e As RepeaterItemEventArgs)
      If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then

         Dim rpt As Repeater = CType(e.Item.FindControl("books"), Repeater)

         If Not (rpt Is Nothing) Then

            doc.Load(Server.MapPath("~/myxml/bookstore.xml"))

            Dim nodes2 As XmlNodeList = doc.SelectNodes("Bookings/Booking[@CLIENT_NO='SA33762']/Products/Book")

            rpt.DataSource = nodes2
            rpt.DataBind()

         End If

      End If
   End Sub

</script>

有什么想法吗?

【问题讨论】:

    标签: asp.net xml vb.net xmlnode itemdatabound


    【解决方案1】:

    我在这里遗漏了什么吗?

    您不能简单地在您的 itemDB Sub 中注释/删除您的 doc.Load(Server.MapPath("~/myxml/bookstore.xml")) 吗?既然您定义了“全局”文档并且已经在页面加载时加载了它? (这样做你已经避免重新加载 xml)

    也就是说,我同意 Caspar 的观点,即您应该使用 XmlDatasource(尤其是对于它的缓存能力),您不必在标记中使用 XmlDatasource - 您始终可以定义它也在您的代码隐藏中 - 因为您担心人们会出于某种原因看到您的 (基于 asp.net 服务器端的) 标记...

    例如

    Public Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
    
        If Not Page.IsPostBack Then
            Dim source As New XmlDataSource()
            source.DataFile = "~/myxml/bookstore.xml"
            source.XPath = "Bookings/Booking[@CLIENT_NO='SA33762']"
            rpMyRepeater.DataSource = source
            rpMyRepeater.DataBind()
        End If
    
    End Sub
    

    标记: (您会注意到这里的好处是,我们使用第一个转发器的源绑定第二个转发器)

    <asp:Repeater ID="rpMyRepeater" runat="server">
        <ItemTemplate>
            <%#XPath("//Booking/NAME/text()")%>
            <asp:Repeater runat="server" ID='books' DataSource='<%#XPathSelect("//Booking/Products/Book") %>'>
                <HeaderTemplate>
                    <h2>
                        Books</h2>
                </HeaderTemplate>
                <ItemTemplate>
                    <p>
                        Title:
                        <%#XPath("TITLE/text()")%></p>
                    <p>
                        <%#XPath("BOOKCODE/text()")%></p>
                </ItemTemplate>
            </asp:Repeater>
        </ItemTemplate>
    </asp:Repeater>
    

    XML

    <?xml version="1.0" encoding="utf-8" ?>
    <Bookings>
      <Booking CLIENT_NO="SA33762">
        <NAME>Mr Pf_Test_15033</NAME>
        <Products>
          <Book>
            <TITLE>My Book</TITLE>
            <BOOKCODE>12345</BOOKCODE>
          </Book>
          <Book>
            <TITLE>My Book2</TITLE>
            <BOOKCODE>123456</BOOKCODE>
          </Book>
        </Products>
      </Booking>
    </Bookings>
    

    使用 ListView 控件(我最喜欢的 asp.net 控件之一) 的实现将如下所示: (如果没有可用的书籍,它将在 EmptyDataTemplate 中显示标记)

    <asp:Repeater ID="rpMyRepeater" runat="server">
        <ItemTemplate>
            <%#XPath("//Booking/NAME/text()")%>
            <asp:ListView runat="server" ID="books" ItemPlaceholderID="phItems" DataSource='<%#XPathSelect("//Booking/Products/Book") %>'>
                <LayoutTemplate>
                    <h2>
                        Books</h2>
                    <asp:PlaceHolder runat="server" ID="phItems"></asp:PlaceHolder>
                </LayoutTemplate>
                <ItemTemplate>
                    <p>
                        Title:
                        <%#XPath("TITLE/text()")%></p>
                    <p>
                        <%#XPath("BOOKCODE/text()")%></p>
                </ItemTemplate>
                <EmptyDataTemplate>
                    <p>
                        Sorry no books available</p>
                </EmptyDataTemplate>
            </asp:ListView>
        </ItemTemplate>
    </asp:Repeater>
    

    【讨论】:

    • 我认为这几乎是完美的......但是,如果不包括“onItemDataBond”,我认为如果客户没有任何产品(其中虽然听起来很奇怪,但有可能)
    • 好吧,你总是可以用repeater代替listview控件,因为listview就像一个EmptyDataTemplate,如果你没有该用户的任何数据,它会自动显示,会快速添加一个例子跨度>
    【解决方案2】:

    使用XmlDatasource 代替自定义代码,更好地测试、调整、优化并满足您的要求。为什么要编写已经在框架中的东西? ;)

     <asp:xmldatasource
        CacheDuration="Infinite"
        id="XmlDataSource1"
        runat="server"
        XPath="Bookings/Booking[@CLIENT_NO='SA33762']" //<-- test this
        datafile="~/myxml/bookstore.xml" />
    

    【讨论】:

    • 听起来不错......虽然我在这里问这个问题,因为我是一个完全的新手,所以它可能没有那么容易!谢谢你的提示。
    • 因为你是一个完全的新手,我鼓励你亲吻你的代码(保持简短和简单)不要开始重新发明轮子;
    • 我明白你的意思,但我知道的一件事是我不使用代码背后的代码,你最终会得到一些没有编译的东西——不是最佳实践,我宁愿学会用最好的方法而不是最简单的方法。
    • 对于试图重新发明轮子的新手来说,有话要说。通过尝试学习,不太成功,最后找到更合适的预建套件:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多