0

I am writing an xml String and i am passing in two different Lists and i want to Loop the items in the List to continue writing the XML.

public class Results
        {
            public List<Guid> itemGuid { get; set; }
            public List<string> storagePath { get; set; }
            public int userId {get; set;}
        }

public void CreateOutput(string inFile, string storagePath, int userId)
        {
            Results results = GetfileInfo(inFile, storagePath);for each of the pages
            CheckinXml(results.itemGuid, results.storagePath , userId); //

        }

public string CheckinXml(List<Guid> itemGuid, List<string> storagePath, int userId)
        {
            XDocument xdoc = new XDocument();
                 xdoc = new XDocument(
                    new XElement("MyList",
                        new XElement("Record",
                            new XElement("ID", itemGuid),
                            new XElement("StoragePath", storagePath),
                            new XElement("UploadedUserID", userId)
                            )
                    )
                );

            string result = xdoc.ToString();
            return result;
        }

currently all the items in the list of itemGuid and the list of storage Path are stored in one string. In my current case i should have three returned XML strings. Should i place the XML in a for loop looping through the list?

Masriyah
  • 2,445
  • 11
  • 49
  • 91
  • Can you provide more information on the use case? It is possible to use the XmlSerializer to turn an object to XML and vise-versa. It makes it ideal since in C# you can work with the objects and then save it to XML for later use. – Justin Aug 15 '13 at 02:21
  • 1
    Not sure if this helps but just a suggestion. Is the Guid and storage path related? If it is I propose you create a class which has three properties Guid, storagepath and userid and then just use Xml Serializer to do the job for you. – Nilesh Aug 15 '13 at 02:22
  • @Justin example: a client submits a file and i read in each page of the file which each page contains its own id and place to store and the id of the person handling it. – Masriyah Aug 15 '13 at 02:28
  • @Nilesh since i am calling this within another method should i place this method in a for loop ? – Masriyah Aug 15 '13 at 02:33
  • @Masriyah There are overloaded CTOR's for XElement. One of which can take an array, so you can use you lists and instead of looping, can use the `ToArray()` method to convert it to an array. – Justin Aug 15 '13 at 02:36
  • @justin is there an example i can refer to? – Masriyah Aug 15 '13 at 02:39
  • @Masriyah You can use [MSDN](http://msdn.microsoft.com/en-us/library/bb302741.aspx). Always a good source. – Justin Aug 15 '13 at 02:41
  • After trying to use it, that isn't quite what you want. I would say you should loop through them and create an array or list of `XElements` from them and then pass that in. – Justin Aug 15 '13 at 02:50
  • @Justin should i place the whole xml process in a loop - looping through the itemGuid? – Masriyah Aug 15 '13 at 03:00
  • Yep you need to loop through the list. You can try this [link](http://stackoverflow.com/questions/8558763/xelement-add-children-nodes-at-run-time). It might help you. – Nilesh Aug 15 '13 at 03:04

1 Answers1

2

Moving from comments to actual post.

Using XDocument and XElement with List

I would process the List<T> separately and then create the document as so:

public string CheckinXml(List<Guid> itemGuid, List<string> storagePath, int uploadUserId)
    {
        var guids = itemGuid.Select(i => new XElement("ID", i)).ToArray();
        var paths = storagePath.Select(i => new XElement("StoragePath", i)).ToArray();

        XDocument xdoc = new XDocument();
        xdoc = new XDocument(
           new XElement("MyList",
               new XElement("Record",
                   new XElement("IDs", guids),
                   new XElement("StoragePaths", paths),
                   new XElement("UploadedUserID", uploadUserId)
                   )
           )
       );

Using this, if I called it with the following call:

var guids = new List<Guid> { new Guid(), new Guid(), new Guid() };
var paths = new List<string> { @"C:\home", @"D:\home", @"E:\home" };
var userId = 1000;

Console.WriteLine(CheckinXml(guids, paths, userId));

The output would be as follows:

<MyList>
  <Record>
    <IDs>
      <ID>00000000-0000-0000-0000-000000000000</ID>
      <ID>00000000-0000-0000-0000-000000000000</ID>
      <ID>00000000-0000-0000-0000-000000000000</ID>
    </IDs>
    <StoragePaths>
      <StoragePath>C:\home</StoragePath>
      <StoragePath>D:\home</StoragePath>
      <StoragePath>E:\home</StoragePath>
    </StoragePaths>
    <UploadedUserID>1000</UploadedUserID>
  </Record>
</MyList>

Now your list is represented correctly.


Example using the XmlSerializer

Some may not like it, but you can use attributes to determine how the xml node names are defined

[XmlRoot(ElementName = "Record")]
public class Results
{
    [XmlArray(ElementName = "Ids"), XmlArrayItem(ElementName = "Id")]
    public List<Guid> itemGuid { get; set; }

    [XmlArray(ElementName = "StoragePaths"), XmlArrayItem(ElementName = "StoragePath")]
    public List<string> storagePath { get; set; }

    [XmlElement(ElementName = "UploadedUserId")]
    public int userId { get; set; }
}

Then using the following code, you can serializer the object:

var results = new Results
    {
      itemGuid = new List<Guid> {new Guid(), new Guid(), new Guid()},
      storagePath =  new List<string>{@"C:\home\", @"D:\home\", @"E:\home\"},
      userId = 1234,
    };

var serializer = new XmlSerializer(results.GetType());

using (var sw = new StringWriter())
{
    serializer.Serialize(sw, results);

    Console.WriteLine(sw.ToString());
}
Community
  • 1
  • 1
Justin
  • 3,337
  • 3
  • 16
  • 27
  • wow great i will go ahead and try this out. I might alter the format so that for each record i will have an id, a path, and the user id. – Masriyah Aug 15 '13 at 03:20
  • @Masriyah I was just using the format that you provided. If you provided a example output it would help getting exactly what you want, but since you have two lists, you might have headaches. For example, how do you know what path goes to what item id? If they are associated in some way, using a `class` to represent this or a `Dictionary` would be better than two lists and trying to make the associative. – Justin Aug 15 '13 at 03:25
  • I have the guid and string coming from a class which returns results – Masriyah Aug 15 '13 at 03:28
  • @Masriyah I would recommend posting the entire class then to see how you have it structured. As mentioned in the comments earlier, perhaps using the XmlSerializer is better suited to what you are trying to accomplish. – Justin Aug 15 '13 at 03:34
  • I really appreciate your help and time. I added more methods above regarding the class – Masriyah Aug 15 '13 at 03:46
  • Did you get the answer? I think what @Justin suggested of having some sort of a class to relate Guids and pahts would make more sense. Or are they not related in your case? – Nilesh Aug 15 '13 at 05:44
  • @Masriyah When you talked about altering the format, where you just talking about the name of the xml nodes or did you want a record to have a single id, a single path, and a single user id? – Justin Aug 15 '13 at 12:58
  • @Masriyah I added an example using the XmlSerializer object. – Justin Aug 15 '13 at 13:25