如何访问中继器中的 XML 子节点

How to access XML subnode in repeater

我正在尝试找出如何在我的 asp.net Web 表单应用程序中使用转发器访问序列化 xml 数据中的子节点。我可以访问第一层上的所有 xml 元素数据,但不能访问第二层(好处)。

我的问题是我无法在中继器内访问 Item.Benefits.BenefitImageItem.Benefits.Benefit

任何指点将不胜感激。

这是我的 xml 数据的片段:

<Category Key="acid" Rank="30">
  <Intro> ... </Intro>
  <Description> ... </Description>
  <Benefits>
    <Benefit Key="promote_texture">Promote smoother skin texture</Benefit>  
    <Benefit Key="promote_tone">Promote even skin tone</Benefit>
    <Benefit Key="enhance_radiance">Enhance skin radiance</Benefit>      
  </Benefits>
</Category>

这里是 .ASPX 页面中转发器的片段:

<asp:Panel runat="server" CssClass="benefits-wrapper">
  <asp:Repeater ID="BenefitsList" runat="server" ItemType="OrdinarySite.Models.ProductCategory" SelectMethod="CategoryList_GetData">
    <ItemTemplate>
      <div class="benefits">                                 
        <div class="benefit">
           <asp:Image runat="server" CssClass="benefit-img" ImageUrl="<%# Item.Benefits.BenefitImage %>" />
           <asp:Label runat="server" CssClass="benefit-desc" Text="<%# Item.Benefits.Benefit %>"></asp:Label>
        </div>                                                               
      </div>
      <div class="benefits-copy">
        <asp:Label runat="server" CssClass="heading" Text="<%# Item.Name %>"></asp:Label>
        <p><%# Item.Description %></p>
      </div>
    </ItemTemplate>
  </asp:Repeater>
</asp:Panel>

这是 .ASPX.CS 页面中转发器的片段:

public partial class Category : BasePage
{
    public string categoryKey;

    protected void Page_Load(object sender, EventArgs e)
    {
        var key = (string)RouteData.Values["key"];

        categoryKey = key;

        if (categoryKey != null) {
            this.Title = categoryKey;
        } else {
            Response.Redirect("~/", true);
        }
    }

    public IEnumerable<ProductCategory> CategoryList_GetData() => CacheObject.Categories.Where(x => x.Key == categoryKey);        
}

这是 class:

的片段
namespace Site.Models
{
[Serializable]
public class ProductCategory : IComparable<ProductCategory>
{
    [XmlAttribute]
    public string Key { get; set; }
    [XmlAttribute]
    public int Rank { get; set; }
    [XmlAttribute]
    public string Naming { get; set; }
    [XmlIgnore]
    public List<Product> Products { get; set; }
    public string Name => Resources.ProductCategory.ResourceManager.GetString(Key);
    public int CompareTo(ProductCategory other) => this.Rank - other.Rank;
    public static string XmlFileName => HostingEnvironment.MapPath("~/App_Data/categories.xml");
    public string Intro { get; set; }
    public string Description { get; set; }

    [XmlArray("Benefits"), XmlArrayItem("Benefit")]
    public List<BenefitsList> Benefits { get; set; }

    [Serializable]
    public class BenefitsList
    {

        [XmlAttribute]
        public string Key { get; set; }
        [XmlElement]
        public string Benefit { get; set; }

        public string BenefitImage => $"~/Images/category/benefits/{Key}.svg";
    }       

    public static List<ProductCategory> LoadXmlData( List<Product> products )
    {
        var cats = SerializerSupport.DeserializeList<ProductCategory>( XmlFileName );
        foreach( var c in cats )
        {
            c.Products = products
                .Where( x => x.Details != null && string.Equals( c.Key, x.Details.CategoryKey, StringComparison.OrdinalIgnoreCase ) )
                .OrderBy(x => x.Details.Title).ToList();
            c.Products.ForEach( x => x.Category = c );
        }

        cats.Sort();
        return cats;
    }
}

您需要使用嵌套转发器在转发器内显示Benefits,如下所示。参见:Nested repeater

<asp:Panel runat="server" CssClass="benefits-wrapper">
  <asp:Repeater ID="BenefitsList" runat="server" ItemType="OrdinarySite.Models.ProductCategory" SelectMethod="CategoryList_GetData">
    <ItemTemplate>
      <div class="benefits">   
        <asp:Repeater runat="server" DataSource='<%# Eval("Item.Benefits") %>'>
            <div class="benefit">
               <asp:Image runat="server" CssClass="benefit-img" ImageUrl="<%# BenefitImage %>" />
               <asp:Label runat="server" CssClass="benefit-desc" Text="<%# Benefit %>"></asp:Label>
            </div>  
        </asp:Repeater>                                                           
      </div>
      <div class="benefits-copy">
        <asp:Label runat="server" CssClass="heading" Text="<%# Item.Name %>"></asp:Label>
        <p><%# Item.Description %></p>
      </div>
    </ItemTemplate>
  </asp:Repeater>
</asp:Panel>