1

I'm learning Web Forms, and I'm trying to convert an order form I had been building. I learned about XmlDataSource to source my XML file and Repeater to build a template to present the data, and all is mostly well.

First a sample of how my XML works, and then the problem:

<items>
    <item id="sheet-1">
        <name>Sheet the First</name>
        <price id="single" />
    </item>

    <item id="sheet-2">
        <name>Sheet the Second</name>
        <price id="double" />
    </item>
</items>

<costs>
    <cost id="single">.10</cost>
    <cost id="double">.20</cost>
    <cost id="triple">.30</cost>
</costs>

With my pre-Web Forms setup, I created a foreach loop to store all of the cost IDs and values in an array, and then when I looped through each item, I matched the price ID to the cost ID and then output the corresponding value.

I'd like to create the same effect within a Repeater. How I saw it in my head was something like this...

<p class="cost-line">
<%#XPath("../../costs/cost[@id='XPath("price/@id")']") %>
</p>

But I knew that that syntax was highly unlikely to work.

I'm not entirely sure how to word the question. I believe what I'm trying to do is use foreign keys with XPath and Repeaters. Is this possible? If not, what alternatives exist to get where I'm trying to go?

Brendan
  • 868
  • 1
  • 16
  • 38
  • http://stackoverflow.com/questions/142010/can-xpath-do-a-foreign-key-lookup-across-two-subtrees-of-an-xml has a similar question, but the answer doesn't help me because this isn't XSLT. – Brendan Oct 22 '12 at 19:24

1 Answers1

1

Assuming you are using XDocument and that you are binding this way :

yourRepeater.DataSource = yourXDocument.Root.Element("items").Elements("item").ToList();
yourRepeater.DataBind();

you can have a getCost method :

protected String getCost(XElement xel) 
  {
   return xel
            .Parent
            .Parent
            .Element("costs")
            .Elements("cost")
            .Where(x=>x.Attribute("id").Value==xel.Element("price").Attribute("id").Value)
            .First().Value;
  }

and then try something like this :

 <p class="cost-line">
    <%#this.getCost((XElement)Container.DataItem) %>
 </p>

hope this will help

jbl
  • 15,179
  • 3
  • 34
  • 101
  • I'm not binding this way though. I just used `` and XPath. Is is possible to work what you did into that setup? This whole scheme is very new to me. – Brendan Oct 25 '12 at 16:52
  • @Brendan , have you tried something like : <%#XPath(String.Format("../../costs/cost[@id='{0}']",XPath("price/@id"))) %> ? – jbl Oct 25 '12 at 19:32
  • Wow...that worked! Can you explain why that worked? Or point me towards an MSDN article that would explain it? Thanks a lot! – Brendan Nov 02 '12 at 21:12
  • 1
    glad it worked ! In fact, repeater with XmlDataSource seems to work pretty well like regular repeater, with the addition that the DataItems are IXPathNavigable. The following question and answer might provide some valuable info : http://stackoverflow.com/a/1814358/1236044 – jbl Nov 05 '12 at 08:57