简体   繁体   中英

Get xml attribute with XDocument based on value of another xml attribute

I have some xml that looks something like:

<forms>
    <form name="admin" title="Admin Info">
        <field name="primary" label="Primary Name" required="false">
        <group desc="General" name="personalinfo" required="false" hide="false">
            <field label="Photos" name="photoupload" required="false" hide="false">
            <field label="First Name" name="firstanme" required="false" hide="false">
        </group>
    </form>
    <form name = "..." etc>
        ....etc...
    </form>
</forms>

I am trying to get information from the inner "field" tag. For example, I want to get the "required" and "hide" values when name="photoupload."

What I have so far:

        XDocument doc = XDocument.Parse(xmlTemplate);
        var photoInfo = doc.Descendants("field")
                                .Where(field => field.Attribute("name").Value == "photoupload")
                                .Select(field => new
                                {
                                    Hide = field.Attribute("hide").Value,
                                    Required = field.Attribute("required").Value
                                })
                                .Single();

        photoInfoTextBox.Text = photoInfo.Hide.ToString();

However, I am getting an " Object reference not set to an instance of an object. " error. My guess is that the code is trying to get info from the first "field" tag (where name="primary"), but actually I want info from the inner field tag, specifically:

forms/form(where name="admin")/group(where desc="general")/field(where name="photoupload").

How would I go about doing this?

Just use casting instead of reading Value property:

    var photoInfo = doc.Descendants("field")
                       .Where(field => (string)field.Attribute("name") == "photoupload")
                       .Select(field => new {
                                Hide = (bool?)field.Attribute("hide"),
                                Required = (bool?)field.Attribute("required")
                       })
                       .Single();

Most likely you have an exception because some field element don't have name attribute. That means field.Attribute("name") will return null . And null.Value will throw NullReferenceException . Note that some elements also don't have hide attribute.

When you cast XAttribute or XElement to type which can have null value, you will get null if attribute or element do not exist. No exceptions will be thrown.

NOTE: Thus you have only one field with given name, you can simply try get that field

var photoUpload = doc.Descendants("field")
                     .Single(f => (string)f.Attribute("name") == "photoupload");

// or
var photoUpload = doc.XPathSelectElement("//field[@name='photoupload']");

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