Commits

Kevin Berridge committed 49f6dc6

Added First, FirstOrDefault, and Where

Comments (0)

Files changed (2)

SimpleXml/SimpleXml.cs

     {
       elements[0].Save(writer, options);
     }
+    
+    public dynamic First(string attributeName, string value)
+    {
+      var match = elements.First(e => e.Attributes().Where(a => a.Name.LocalName == attributeName && a.Value == value).Count() > 0);
+      if (match.HasElements) return new SimpleXml(match);
+      else return match.Value;
+    }
+
+    public dynamic FirstOrDefault(string attributeName, string value)
+    {
+      var match = elements.FirstOrDefault(e => e.Attributes().Where(a => a.Name.LocalName == attributeName && a.Value == value).Count() > 0);
+      if (match == null) return null;
+      if (match.HasElements) return new SimpleXml(match);
+      else return match.Value;
+    }
+
+    public dynamic Where(string attributeName, string value)
+    {
+      var matches = elements.Where(e => e.Attributes().Where(a => a.Name.LocalName == attributeName && a.Value == value).Count() > 0);
+      if (matches.All(n => n.HasElements))
+        return new SimpleXml(matches);
+      else
+        return matches.Select(n => n.Value).ToList();
+    }
 
     /// <summary>
     /// The first property access is a special case because the XElement is already at the root level, 

SimpleXmlTests/SimpleXmlReading.cs

       dynamic x = XmlStrings.NamedXmlNs;
       Assert.AreEqual("Blogs", x.section.title);
     }
+
+    [Test]
+    public void FirstWithValue()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.AreEqual("value2", x.root.node.First("name", "b"));
+    }
+
+    [Test]
+    public void FirstWithChildElements()
+    {
+      dynamic x = "<root><node name='a'><child>value</child></node><node name='b'><child>value2</child></node><node name='c'><child>value3</child></node></root>".AsSimpleXml();
+      Assert.AreEqual("value2", x.root.node.First("name", "b").child);
+    }
+
+    [Test]
+    public void FirstWithNoMatchingValue()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.Catch<InvalidOperationException>(() => { x.root.node.First("name", "d"); });
+    }
+
+    [Test]
+    public void FirstWithNoMatchingAttribute()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.Catch<InvalidOperationException>(() => { x.root.node.First("missing", "d"); });
+    }
+
+    [Test]
+    public void FirstOrDefaultWithValue()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.AreEqual("value2", x.root.node.FirstOrDefault("name", "b"));
+    }
+
+    [Test]
+    public void FirstOrDefaultWithChildElements()
+    {
+      dynamic x = "<root><node name='a'><child>value</child></node><node name='b'><child>value2</child></node><node name='c'><child>value3</child></node></root>".AsSimpleXml();
+      Assert.AreEqual("value2", x.root.node.FirstOrDefault("name", "b").child);
+    }
+
+    [Test]
+    public void FirstOrDefaultWithNoMatchingValue()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.IsNull(x.root.node.FirstOrDefault("name", "d"));
+    }
+
+    [Test]
+    public void FirstOrDefaultWithNoMatchingAttribute()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='c'>value3></node></root>".AsSimpleXml();
+      Assert.IsNull(x.root.node.FirstOrDefault("missing", "d"));
+    }
+    [Test]
+    public void WhereWithValue()
+    {
+      dynamic x = "<root><node name='a'>value</node><node name='b'>value2</node><node name='b'>value3></node></root>".AsSimpleXml();
+      var matches = x.root.node.Where("name", "b");
+      Assert.Contains("value2", matches);
+      Assert.Contains("value2", matches);
+    }
+
+    [Test]
+    public void WhereWithChildElements()
+    {
+      dynamic x = "<root><node name='a'><child>value</child></node><node name='b'><child>value2</child></node><node name='b'><child>value3</child></node></root>".AsSimpleXml();
+      var matches = x.root.node.Where("name", "b").child;
+      Assert.Contains("value2", matches);
+      Assert.Contains("value2", matches);
+    }
   }
 }