Returning from the Ruby world with its XML-to-hash mapping easiness I am looking forward to see something similar in C#.
Here is the source XML:
<whois-resources xmlns:xlink="http://www.w3.org/1999/xlink">
    <service name="search"/>
    <parameters>
        <inverse-lookup/>
        <type-filters/>
        <flags/>
        <query-strings>
            <query-string value="....."/>
        </query-strings>
        <sources/>
    </parameters>
    <objects>
        <object type="inetnum">
            <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/inetnum/....."/>
            <source id="ripe"/>
            <primary-key>
                <attribute name="inetnum" value="....."/>
            </primary-key>
            <attributes>
                <attribute name="inetnum" value="....."/>
                <attribute name="netname" value="....."/>
                <attribute name="descr" value="....."/>
                <attribute name="descr" value="....."/>
                <attribute name="country" value="....."/>
                <attribute name="admin-c" value="....." referenced-type="person">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
                </attribute>
                <attribute name="tech-c" value="....." referenced-type="person">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
                </attribute>
                <attribute name="status" value="ASSIGNED PA"/>
                <attribute name="mnt-by" value="....." referenced-type="mntner">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
                </attribute>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="source" value="....." comment="Filtered"/>
            </attributes>
            <tags>
                <tag id="RIPE-USER-RESOURCE"/>
            </tags>
        </object>
        <object type="person">
            <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
            <source id="ripe"/>
            <primary-key>
                <attribute name="nic-hdl" value="....."/>
            </primary-key>
            <attributes>
                <attribute name="person" value="....."/>
                <attribute name="address" value="....."/>
                <attribute name="address" value="....."/>
                <attribute name="address" value="....."/>
                <attribute name="phone" value="....."/>
                <attribute name="fax-no" value="....."/>
                <attribute name="nic-hdl" value="....."/>
                <attribute name="mnt-by" value="....." referenced-type="mntner">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
                </attribute>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="source" value="....." comment="Filtered"/>
            </attributes>
        </object>
        <object type="route">
            <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/route/....."/>
            <source id="ripe"/>
            <primary-key>
                <attribute name="route" value="....."/>
                <attribute name="origin" value="....."/>
            </primary-key>
            <attributes>
                <attribute name="route" value="....."/>
                <attribute name="descr" value="....."/>
                <attribute name="origin" value="....." referenced-type="aut-num">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/aut-num/....."/>
                </attribute>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="remarks" value="....."/>
                <attribute name="mnt-by" value="....." referenced-type="mntner">
                    <link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
                </attribute>
                <attribute name="source" value="....." comment="Filtered"/>
            </attributes>
        </object>
    </objects>
    <terms-and-conditions xlink:type="locator" xlink:href="http://www.ripe.net/db/support/db-terms-conditions.pdf"/>
</whois-resources>
which I would like to remap to an object with following structure:
{
    Service: {
        Name: "....."
    },
    Parameters: {
        QueryStrings: [".....", "....."]
    },
    Inetnum: {
        Link: {
            Type: ".....",
            Href: "....."
        },
        Source: {
            id: "....."
        },
        PrimaryKey: {
            Inetnum: "....."
        },
        Attr: {
            Inetnum: ".....",
            Netname: ".....",
            Descr: ".....",
            Country: ".....",
            AdminC: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            },
            TechC: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            },
            Status: ".....",
            MntBy: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            }
            Remarks: ".....", #a concatenation of all remarks nodes
            Source: {
                Value: ".....",
                Comment: "....."
            }
        },
        Tags: [
            { id: "....." }
        ]
    },
    Person {
        Link: {
            Type: ".....",
            Href: "....."
        },
        Source: {
            id: "....."
        }
        PrimaryKey: {
            NicHdl: "....."
        },
        Attr: {
            Person: ".....",
            Address: ".....", #a concatenation of all address nodes
            Phone: ".....",
            FaxNo: ".....",
            NicHdl: ".....",
            MntBy: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            }
            Remarks: ".....", #a concatenation of all remarks nodes
            Source: {
                Value: ".....",
                Comment: "....."
            }
        }
    },  
    Route: {
        Link: {
            Type: ".....",
            Href: "....."
        },
        Source: {
            id: "....."
        },
        PrimaryKey: {
            Route: ".....",
            Origin: "....."
        },
        Attr: {
            Route: ".....",
            Descr: ".....",
            Origin: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            },
            Remarks: ".....", #a concatenation of all remarks nodes
            MntBy: {
                Value: ".....",
                ReferencedType: ".....",
                Link: {
                    Type: ".....",
                    Href: "....."
                }
            },
            Source: {
                Value: ".....",
                Comment: "....."
            }
        }
    },
    TermsAndConditions: {
        Type: ".....",
        Href: "....."
    }
}
to be able to call properties like:
whois.Inetnum.Attr.Netname
I completely dislike an idea to retrieve each node by calling SelectSingleNode("xpath");
The desired process is:
- Define receiver object and all its subobjects
- Define mapping rules
- Parse XML string with a single method call
 
    