简体   繁体   中英

C# XmlDocument: Nested objects

I have a XML file that has this following format:

<datasources>
    <datasource name="...">
        <column caption="..." name="..."> ... </column>
        <column caption="..." name="..."> ... </column>
    </datasource>
    <datasource name="...">
        <column caption="..." name="..."> ... </column>
        <column caption="..." name="..."> ... </column>
    </datasource>
</datasources>
...

and I want to get a caption - name map for columns that meets specific criteria (that is, has an expected caption and is a column of an expected datasource ).

Currently I have this code but I'm not confident of it.

XmlReader reader = XmlReader.Create(new StringReader(content));
while (reader.ReadToFollowing("datasource"))
{
    reader.MoveToAttribute("name");
    if (reader.Value == dsName)
    {
        while (reader.ReadToFollowing("column"))
        {
            reader.MoveToAttribute("caption");
            if (captions.Contains(reader.Value))
            {
                String cap = reader.Value;
                reader.MoveToAttribute("name");
                local_caps.Add(new KeyValuePair<String, String>(reader.Value, cap));
            }
        }
    }
}

My concern is that, would the inner while loop (looking for all column s) read all the way towards the end of the file and hence go out of its supposed scope (within its datasource )? If so, how should I avoid it? Thanks a lot!

This is ideal job for XPath :

doc.Load("file.xml");
var nodes = doc.SelectNodes("/datasources/datasource[@name='DS1']/column[@caption='C1']");

Of course, to get your map, you have to improve this sample a little:

string expectedDatasource = "DS1";
string expectedCaption = "C1";
string xpath = string.Format("/datasources/datasource[@name='{0}']/column[@caption='{1}']",
                             expectedDatasource, expectedCaption)
var local_caps = doc.SelectNodes(xpath)
                    .Cast<XmlElement>()
                    .ToDictionary(x => x.GetAttribute("name"), 
                                  x => x.GetAttribute("caption"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM