4 thoughts on “New version of XMLSlurper”

  1. Hey there, I love the library. One question, how do I handle nodes that may have one child OR many children? I know it makes a ____List out of cases with more than one child. But when there’s just one, that ____List doesn’t exist, and I’m not sure how to check for that without a runtime error.

    00000138160545582439

    701937595934
    C28489
    M
    9
    PAA
    0006

    00000138160544994455

    192004172040
    C29835
    M
    8
    PAA
    0005

    192004172057
    C29835
    M
    8.5
    PAA
    0007

  2. Ηι Sunil!

    Le me see if I understand your question correctly: you’re parsing xml files, let’s say they look like this (simplified):

    order
    – item 1
    – item 2
    – item 3

    This would of course create order.ItemList. But when the order happens to have just 1 item:

    order
    – item 1

    Then XmlSlurper will create order.Item.

    And you don’t know how to check that without a runtime error.

    Is that your question?

  3. If so, here’s the solution:

    (short version)

    var orderDict = order as ToStringExpandoObject;
    bool hasMemberItem = orderDict.Members.ContainsKey("item");
    Console.WriteLine($"Has Item = {hasMemberItem}");
    
    bool hasMemberItemList = orderDict.Members.ContainsKey("ItemList");
    Console.WriteLine($"Has ItemList = {hasMemberItemList}");            
    
    if (hasMemberItem)
    {
        Console.WriteLine($"Item = {order.Item}");
    }
    if (hasMemberItemList)
    {
        Console.WriteLine($"ItemList = {order.ItemList}");
    }
    

    (slightly not-so-short version)

    Here’s why this works:

    The parsed xml object is returned as dynamic, so that you can write myObj.anything and the compiler won’t complain –you, the programmer, promise that in runtime it will be ok.

    But behind the scenes it’s actually a kind-of IDictionary, a class called ToStringExpandoObject (you can see the code here). So you can cast the object as ToStringExpandoObject (the 1st line above) and then access its myObj.Members property. This is a proper IDictionary! So you can use, as above, myObj.Members.ContainsKey(“whatever”) to find out if you have a property with a given name.

    The code above works in both cases because, on runtime, the line with order.Item (and order.ItemList) will only be reached if the property exists, due to the guard condition.

    Hope this helps!

    1. That was exactly my question. As a work around, I originally used try{}catch{} (if accessing order.ItemList causes an exception, we access order.Item in the catch block). This isn’t good practice, so thanks for the reply!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s