tags:

views:

154

answers:

2

Hello,
I have a large xml file and want to get a defined number of <Cooperation> nodes from it. What's the best way to handle this.

Currently, I'm using this code

public string FullCooperationListChunkGet(int part, int chunksize)
{
    StringBuilder output_xml = new StringBuilder();
    IEnumerable<XElement> childList = from el in xml.Elements("Cooperations").Skip(part * chunksize).Take(chunksize) select el;

    foreach (XElement x in childList.Elements())
    {
        output_xml.Append(x.ToString());
    }

    return output_xml.ToString();
}

Skip(part * chunksize).Take(chunksize) doesn't work (seems to be only valid for the Cooperations Tag and not the Cooperation Tags)

Can somebody point me in the right direction.

Thanks,
rAyt

Edit:
The Background is this: I'm pushing these xml parts via a webservice to a Blackberry. Unfortunately, the http request size on a blackberry enterprise server is limited to 256 kb by default.

Part of the XML File:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Cooperations>
  <Cooperation>
    <CooperationId>xxx</CooperationId>
    <CooperationName>xxx</CooperationName>
    <LogicalCustomers>
      <LogicalCustomer>
        <LogicalCustomerId>xxx</LogicalCustomerId>
        <LogicalCustomerName>xxx</LogicalCustomerName>
        <Customers>
          <Customer>
            <CustomerId>xxx</CustomerId>
            <CustomerName>xxx/CustomerName>
          </Customer>
          <Customer>
            <CustomerId>xxx</CustomerId>
            <CustomerName>xxx</CustomerName>
          </Customer>
        </Customers>
      </LogicalCustomer>
      <LogicalCustomer>
        <LogicalCustomerId>xxx</LogicalCustomerId>
        <LogicalCustomerName>xxx</LogicalCustomerName>
        <Customers>
          <Customer>
            <CustomerId>xxx</CustomerId>
            <CustomerName>xxx</CustomerName>
          </Customer>
          <Customer>
            <CustomerId>xxx</CustomerId>
            <CustomerName>xxx</CustomerName>
          </Customer>
        </Customers>
      </LogicalCustomer>
      <LogicalCustomer>
        <LogicalCustomerId>xxx</LogicalCustomerId>
        <LogicalCustomerName>xxx</LogicalCustomerName>
        <Customers>
          <Customer>
            <CustomerId>xxx</CustomerId>
            <CustomerName>xxx</CustomerName>
          </Customer>
        </Customers>
      </LogicalCustomer>
    </LogicalCustomers>
  </Cooperation>
  <Cooperation>
  ...
+2  A: 

For using XDocument, I expect you want something like:

var qry = doc.Root.Elements("Cooperation").Skip(part*chunksize).Take(chunksize);

however, if the data is large, you might have to drop down to XmlReader instead... I'll try to do an example... (update; 512kb probably isn't worth it...)

The problem with your code is that you are using .Elements() here:

foreach (XElement x in childList.Elements())
{
    output_xml.Append(x.ToString());
}

Just remove that:

foreach (XElement x in childList)
{
    output_xml.Append(x.ToString());
}

For info - you are also using query syntax unnecessarily:

IEnumerable<XElement> childList = from el in xml.Elements("Cooperations")
    .Skip(part * chunksize).Take(chunksize) select el;

is 100% identical to:

IEnumerable<XElement> childList = xml.Elements("Cooperations")
    .Skip(part * chunksize).Take(chunksize);

(since the compiler ignores an obvious select, without mapping it to the Select LINQ method)

Marc Gravell
Hi Marc, I already tried that. But then the opening and closing <cooperation> tags are missing.
Henrik P. Hessel
cannot reproduce... if you mean the `<Cooperations>` tags are missing... then add them manually?
Marc Gravell
the output starts with <CooperationId>xxx ... and not the opening tag <Cooperation>
Henrik P. Hessel
"Cooperation" issue fixed above...
Marc Gravell
d'oh... yes, fixed!
Henrik P. Hessel
+1  A: 

Do you have an xml document or a fragment, i.e do you have more than 1 "Cooperations" nodes? If you have more, which Coopertation's are you expecting to get? From just 1 Cooperations or across multiple, reason for asking is that you have written xml.Element**s**("Cooperations").

Wouldn't this do the trick:

xml.Element("Cooperations").Elements("Cooperation").Skip(...).Take(...)
veggerby
No.. only one <Cooperations> Tag.
Henrik P. Hessel
Thanks, but the cooperation tags are missing here, too.
Henrik P. Hessel
foreach (var xx in x.Element("Cooperations").Elements("Cooperation").Skip(2).Take(3)){ Console.WriteLine(xx.Name);}give me "Cooperation"*3...
veggerby