代码之家  ›  专栏  ›  技术社区  ›  Robert Harvey

如何为这个Linq to XML函数编写Lambda语句?

  •  1
  • Robert Harvey  · 技术社区  · 15 年前

    我正在和 this XSD file. 与此问题相关的XML部分如下:

    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns="https://wsmrc2vger.wsmr.army.mil/rcc/manuals/106-11" 
               targetNamespace="https://wsmrc2vger.wsmr.army.mil/rcc/manuals/106-11"
               elementFormDefault="qualified" 
               attributeFormDefault="unqualified">
        <xs:element name="Tmats">
            <xs:complexType>
                <xs:sequence>
                    <xs:annotation>
                        <xs:documentation>TMATS G Group</xs:documentation>
                    </xs:annotation>
                    <xs:element name="ProgramName" type="xs:string" minOccurs="0">
                        <xs:annotation>
                            <xs:documentation>PN</xs:documentation>
                        </xs:annotation>
                    </xs:element>
    

    为了得到 documentation 给定值 xs:element ,我有一个小函数,它递归地遍历子节点,直到找到 文档

    public string GetCode(XElement e)
    {
        foreach (var s in e.Elements())
        {
            // If we hit an intervening element, bail out.
            if (s.Name.ToString().Contains("element"))
                return "";
    
            if (s.Name.ToString().Contains("annotation"))
            {
                // I'll explain this loop in a moment.
                foreach (var t in s.Elements())
                {
                    if (t.Name.ToString().Contains("documentation"))
                        return t.Value;
                }
            } 
            else
                return GetCode(s);
        }
        return "";
    }
    

    到现在为止,一直都还不错。单元测试如下所示:

    [TestMethod()]
    public void GetCodeTest()
    {
        string path = @"C:\Documents and Settings\harvey robert\Desktop\Tmats.xsd";
    
        IEnumerable<XElement> elements =
            from e in XElement.Load(path).Elements()
            select e;
    
        TmatsDictionary target = new TmatsDictionary(); 
        XElement x = elements.First();
        string actual = target.GetCode(x);
        Assert.AreEqual("TMATS G Group", actual);
    }
    

        XElement z = elements.DescendantsAndSelf()
                             .First(y => y.Attribute("name")
                             .ToString().Contains("ProgramName"));
    
        actual = target.GetCode(z);
        Assert.AreEqual("PN", actual);
    

    …但是 由于对象引用为空,此操作失败 y.Attribute("name") ).

    // I'll explain this loop in a moment.
    foreach (var t in s.Elements())
    {
        if (t.Name.ToString().Contains("documentation"))
            return t.Value;
    }
    

    这样写是因为 我不知道如何在一个有效的Lambda语句中表示条件。

    有什么建议吗?

    4 回复  |  直到 15 年前
        1
  •  1
  •   Robert Harvey    15 年前

    您需要使用名称空间:

    XNamespace ns = "https://wsmrc2vger.wsmr.army.mil/rcc/manuals/106-11";
    XElement z = elements.DescendantsAndSelf()
                         .First(y => y.Attribute(ns + "name")
                             .Value.Contains("ProgramName"));
    
        2
  •  1
  •   TalentTuner    15 年前

    试试这个

    elements.DescendantsAndSelf().
                    First(y => y.Attribute(XName.Get("name", "http://www.w3.org/2001/XMLSchema")));
    
        3
  •  1
  •   Gabe Timothy Khouri    15 年前

    y.Attribute("name").ToString().Contains("ProgramName") 将在不包含“name”属性的每个元素上失败。你需要这样的东西:

    y.Attribute("name") != null &&
    y.Attribute("name").ToString().Contains("ProgramName");
    

    <element> 要包含的元素 name 属性,可以忽略空检查并执行以下操作:

    XElement z = elements.DescendantsAndSelf(
                             "{http://www.w3.org/2001/XMLSchema}element")
                         .First(y => y.Attribute("name") 
                         .ToString().Contains("ProgramName"));
    

    编辑:注意,我添加了扩展名以包含名称空间URL。看看是否有效。

        4
  •  0
  •   Robert Harvey    15 年前

    注意呼叫 GetName() 中的方法 DescendantsAndSelf() 打电话来。这将返回格式正确的URI,该URI以表单的名称为前缀 {http://www.w3.org/2001/XMLSchema}element xs:element 名字。

    后代和自身() 仅返回具有名称的那些元素 xs:元素 Attributes 收藏)。

    [TestMethod()]
    public void GetCodeTest()
    {
        string path = @"C:\TestArea\Tmats_09-2010.xml";
    
        IEnumerable<XElement> elements =
            from e in XElement.Load(path).Elements()
            select e;
    
        TmatsDictionary target = new TmatsDictionary();            
        XNamespace ns = "http://www.w3.org/2001/XMLSchema";
    
        XElement z = elements.DescendantsAndSelf(ns.GetName("element")) 
                             .First(y => y.Attribute("name")
                             .Value.Equals("ProgramName"));
    
        actual = target.GetCode(z);
        Assert.AreEqual("PN", actual);
    }