开发者

How to conditionally filter an XmlDataSource of a repeater based on a parents value

I am trying to build a product detail page menu navigation and want to only show the navigation items for products that are in the same category.

The data is maintained in two different XML files. One containing the current product data, and one containing the navigation information. Both contain "category" as an element.

I would like to use another XmlDataSource and then pass in the current products category from the parent container, accessible using XPath("category"), to the XPath attribute to filter the values.

I would then pass this filtered data source to a repeater for rendering.

<%-- get the current product XML --%>
<asp:XmlDataSource ID="productDS" runat="server" XPath="/product" DataFile="~/App_Theme/project/products/poduct1.xml"/> 
<asp:DataList ID="product" DataSourceID="productDS" runat="server">
<ItemTemplate>
     <%-- 
        get the navigation XML and filter the nodes to only show the navItems with the current product category
     --%>       
     <asp:XmlDataSource ID="navItemsDS" runat开发者_高级运维="server" XPath="/navigation/navItems/navItem[category='<%# XPath("category") %>']"  DataFile="~/App_Theme/project/productslist.xml"/> 

     <asp:Repeater ID="Repeater1" runat="server" DataSourceID="navItemsDS" >
         <HeaderTemplate> 
            <ul>
         </HeaderTemplate>
        <ItemTemplate>
            <li><a href="productdetail.html?page=products&amp;id=<%# XPath("prodctid") %>"><%# XPath("producttitle") %></a></li>
        </ItemTemplate>
        <FooterTemplate>
            </ul>
        </FooterTemplate>
     </asp:Repeater>

     ... etc

This does not work however.

How do I go about achieving this in .NET 2.0.


Personally, I'd load the XML into a DataSet and define Relations to map Parent to Child.

See here for general approach.


Solved my own question.

I ended up using the code behind ItemDataBound approach as follows;

asp code;

<%-- get the current product XML --%>
<asp:XmlDataSource ID="productDS" runat="server" XPath="/product" DataFile="~/App_Theme/project/products/poduct1.xml"/> 
<asp:DataList ID="product" DataSourceID="productDS" runat="server">
<ItemTemplate>
     <%-- 
        get the navigation XML and filter the nodes to only show the navItems with the current product category
     --%>       
     <asp:XmlDataSource ID="navItemsDS" runat="server" XPath="/navigation/navItems/navItem"  DataFile="~/App_Theme/project/productslist.xml"/> 

     <asp:Repeater ID="Repeater1" runat="server" DataSourceID="navItemsDS" OnItemDataBound="navigation_ItemDataBound">
         <HeaderTemplate> 
            <ul>
         </HeaderTemplate>
        <ItemTemplate>
            <li><a href="productdetail.html?page=products&amp;id=<%# XPath("prodctid") %>"><%# XPath("producttitle") %></a></li>
        </ItemTemplate>
        <FooterTemplate>
            </ul>
        </FooterTemplate>
     </asp:Repeater>

code behind;

// hides navigation items that are not in the same category as this product.
public void navigation_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    // get a navigator for the current navigation item xml
    XPathNavigator nav = ((IXPathNavigable)e.Item.DataItem).CreateNavigator();
    // get a navigator for the product xml
    XPathNavigator nav2 =((IXPathNavigable)((DataListItem)e.Item.Parent.Parent).DataItem).CreateNavigator();

    String itemCategory = nav.SelectSingleNode("category").Value;
    String productCategory = nav2.SelectSingleNode("category").Value;

    if (itemCategory != productCategory)
    {
        e.Item.Visible = false;
    }
}

Finding the data item of the DataList, i.e. e.item.Parent.Parent.DataItem was a initially difficult to work out.

Then getting at the actual XML Nodes values was a bit obscure.

The code presented above works for me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜