使用XDocument根据另一个xml属性

时间:2016-03-14 22:49:03

标签: c# xml linq-to-xml

我有一些看起来像这样的xml:

<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>

我正在尝试从内部“字段”标记中获取信息。例如,我想在name =“photoupload。”时获得“必需”和“隐藏”值。

到目前为止我所拥有的:

        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();

但是,我收到“Object reference not set to an instance of an object.”错误。我的猜测是代码试图从第一个“field”标签获取信息(其中name =“primary”),但实际上我想要内部字段标签的信息,具体来说:

表格/表格(其中name =“admin”)/ group(其中desc =“general”)/ field(其中name =“photoupload”)。

我将如何做到这一点?

1 个答案:

答案 0 :(得分:1)

只需使用强制转换而不是阅读Value属性:

    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();

您很可能会遇到异常,因为某些field元素没有name属性。这意味着field.Attribute("name")将返回null。而null.Value会抛出NullReferenceException。请注意,某些元素也没有hide属性。

当您将XAttributeXElement投射到可以具有null值的类型时,如果属性或元素不存在,您将获得null。不会抛出异常。

注意:因此,您只有一个field具有指定名称,您只需尝试获取该字段

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

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