diff options
author | Atsushi Eno <atsushieno@gmail.com> | 2005-12-13 18:18:30 +0300 |
---|---|---|
committer | Atsushi Eno <atsushieno@gmail.com> | 2005-12-13 18:18:30 +0300 |
commit | 229263cfc1c08cdba0f50d3a8c38101aef243e93 (patch) | |
tree | 508fcafaba92df38cafae9c0773a72cc779cdd2b /mcs/class/System.XML | |
parent | 502f0ff923a9f3f03681890c3e5bba48c547b299 (diff) |
2005-12-13 Atsushi Enomoto <atsushi@ximian.com>
* XPathNavigator.cs : Reimplemented MoveToFollowing() to avoid
inefficient MoveToDescendant() and to match .NET 2.0 behavior.
* XPathEditableNavigatorTests.cs : added tests for MoveToFollowing().
svn path=/trunk/mcs/; revision=54296
Diffstat (limited to 'mcs/class/System.XML')
4 files changed, 96 insertions, 47 deletions
diff --git a/mcs/class/System.XML/System.Xml.XPath/ChangeLog b/mcs/class/System.XML/System.Xml.XPath/ChangeLog index c640d57f1a2..ac73bb0c65e 100644 --- a/mcs/class/System.XML/System.Xml.XPath/ChangeLog +++ b/mcs/class/System.XML/System.Xml.XPath/ChangeLog @@ -1,5 +1,10 @@ 2005-12-13 Atsushi Enomoto <atsushi@ximian.com> + * XPathNavigator.cs : Reimplemented MoveToFollowing() to avoid + inefficient MoveToDescendant() and to match .NET 2.0 behavior. + +2005-12-13 Atsushi Enomoto <atsushi@ximian.com> + * XPathNavigator.cs : ReplaceSelf() should allow document fragment. Moved implementation to XPathEditableDocument. diff --git a/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs b/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs index 85a6f781158..ec8831684fe 100644 --- a/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs +++ b/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs @@ -721,16 +721,6 @@ namespace System.Xml.XPath return MoveTo (SelectChildren (localName, namespaceURI)); } - bool MoveToDescendant (XPathNodeType type) - { - return MoveTo (SelectDescendants (type, false)); - } - - bool MoveToDescendant (string localName, string namespaceURI) - { - return MoveTo (SelectDescendants (localName, namespaceURI, false)); - } - public virtual bool MoveToNext (string localName, string namespaceURI) { XPathNavigator nav = Clone (); @@ -756,76 +746,89 @@ namespace System.Xml.XPath return false; } - [MonoTODO] public virtual bool MoveToFollowing (string localName, string namespaceURI) { return MoveToFollowing (localName, namespaceURI, null); } - [MonoTODO] public virtual bool MoveToFollowing (string localName, string namespaceURI, XPathNavigator end) { + if (localName == null) + throw new ArgumentNullException ("localName"); + if (namespaceURI == null) + throw new ArgumentNullException ("namespaceURI"); + localName = NameTable.Get (localName); + if (localName == null) + return false; + namespaceURI = NameTable.Get (namespaceURI); + if (namespaceURI == null) + return false; + XPathNavigator nav = Clone (); - bool skip = false; + switch (nav.NodeType) { + case XPathNodeType.Attribute: + case XPathNodeType.Namespace: + nav.MoveToParent (); + break; + } do { - if (!skip && nav.MoveToDescendant (localName, - namespaceURI)) { - if (end != null) { - switch (nav.ComparePosition (end)) { - case XmlNodeOrder.After: - case XmlNodeOrder.Unknown: - return false; + if (!nav.MoveToFirstChild ()) { + do { + if (!nav.MoveToNext ()) { + if (!nav.MoveToParent ()) + return false; } - } + else + break; + } while (true); + } + if (end != null && end.IsSamePosition (nav)) + return false; + if (object.ReferenceEquals (localName, nav.LocalName) && + object.ReferenceEquals (namespaceURI, nav.NamespaceURI)) { MoveTo (nav); return true; } - else - skip = false; - if (!nav.MoveToNext ()) { - if (!nav.MoveToParent ()) - break; - skip = true; - } } while (true); - return false; } - [MonoTODO] public virtual bool MoveToFollowing (XPathNodeType type) { return MoveToFollowing (type, null); } - [MonoTODO] public virtual bool MoveToFollowing (XPathNodeType type, XPathNavigator end) { + if (type == XPathNodeType.Root) + return false; // will never match XPathNavigator nav = Clone (); - bool skip = false; + switch (nav.NodeType) { + case XPathNodeType.Attribute: + case XPathNodeType.Namespace: + nav.MoveToParent (); + break; + } do { - if (!skip && nav.MoveToDescendant (type)) { - if (end != null) { - switch (nav.ComparePosition (end)) { - case XmlNodeOrder.After: - case XmlNodeOrder.Unknown: - return false; + if (!nav.MoveToFirstChild ()) { + do { + if (!nav.MoveToNext ()) { + if (!nav.MoveToParent ()) + return false; } - } + else + break; + } while (true); + } + if (end != null && end.IsSamePosition (nav)) + return false; + if (nav.NodeType == type) { MoveTo (nav); return true; } - else - skip = false; - if (!nav.MoveToNext ()) { - if (!nav.MoveToParent ()) - break; - skip = true; - } } while (true); - return false; } [MonoTODO] diff --git a/mcs/class/System.XML/Test/System.Xml.XPath/ChangeLog b/mcs/class/System.XML/Test/System.Xml.XPath/ChangeLog index dae544e70c2..f607d14569b 100644 --- a/mcs/class/System.XML/Test/System.Xml.XPath/ChangeLog +++ b/mcs/class/System.XML/Test/System.Xml.XPath/ChangeLog @@ -1,5 +1,9 @@ 2005-12-13 Atsushi Enomoto <atsushi@ximian.com> + * XPathEditableNavigatorTests.cs : added tests for MoveToFollowing(). + +2005-12-13 Atsushi Enomoto <atsushi@ximian.com> + * XPathEditableNavigatorTests.cs : added tests that passes empty string to editor methods. Added tests for ReplaceSelf(). diff --git a/mcs/class/System.XML/Test/System.Xml.XPath/XPathEditableNavigatorTests.cs b/mcs/class/System.XML/Test/System.Xml.XPath/XPathEditableNavigatorTests.cs index 9538938fba4..63be82202eb 100644 --- a/mcs/class/System.XML/Test/System.Xml.XPath/XPathEditableNavigatorTests.cs +++ b/mcs/class/System.XML/Test/System.Xml.XPath/XPathEditableNavigatorTests.cs @@ -702,6 +702,43 @@ namespace MonoTests.System.Xml.XPath true, // HasChildren false); // IsEmptyElement } + + [Test] + public void MoveToFollowing () + { + XPathNavigator end; + + XPathNavigator nav = GetInstance ("<root><bar><foo attr='v1'><baz><foo attr='v2'/></baz></foo></bar><dummy/><foo attr='v3'></foo></root>"); + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#1"); + Assert.AreEqual ("v1", nav.GetAttribute ("attr", String.Empty), "#2"); + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#3"); + Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#4"); + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#5"); + Assert.AreEqual ("v3", nav.GetAttribute ("attr", String.Empty), "#6"); + + // round 2 + end = nav.Clone (); + + nav.MoveToRoot (); + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty, end), "#7"); + Assert.AreEqual ("v1", nav.GetAttribute ("attr", String.Empty), "#8"); + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty, end), "#9"); + Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#10"); + // end is exclusive + Assert.IsFalse (nav.MoveToFollowing ("foo", String.Empty, end), "#11"); + // in this case it never moves to somewhere else. + Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#12"); + } + + [Test] + public void MoveToFollowingFromAttribute () + { + XPathNavigator nav = GetInstance ("<root a='b'><foo/></root>"); + nav.MoveToFirstChild (); + nav.MoveToFirstAttribute (); + // should first move to owner element and go on. + Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty)); + } } } |