Skip to content

XmlReader.IsStartElement namespace argument should allow null #41461

Closed

Description

@eerhardt

Background and Motivation

XmlReader has 3 overloads of IsStartElement:

public virtual bool IsStartElement() { throw null; }
public virtual bool IsStartElement(string name) { throw null; }
public virtual bool IsStartElement(string localname, string ns) { throw null; }

Calling the last overload with ns == null doesn't act like calling the middle overload. In other places in XmlReader, the "namespace" parameter is optional and marked with string?, but this one is being annotated as non-nullable because if you passed in null, it would always return false.

In the .NET Design Guidelines we have:

✔️ DO allow null to be passed for optional arguments.

We should consider changing this overload to be string? ns, and making this API act accordingly.

Proposed API

namespace System.Xml
{
    public abstract class XmlReader
    {
        public virtual bool IsStartElement() { } 
        public virtual bool IsStartElement(string name) { } 
-       public virtual bool IsStartElement(string localname, string ns) { } 
+       public virtual bool IsStartElement(string localname, string? ns) { } 

Usage Examples

XmlReader r = ...;

string? ns = GetOptionalNamespace();
r.IsStartElement("Customer", ns);

As the API exists today, callers will instead be forced to check for null and call the other overload themselves:

XmlReader r = ...;

string? ns = GetOptionalNamespace();
if (ns == null)
{
    r.IsStartElement("Customer");
}
else
{
    r.IsStartElement("Customer", ns);
}

Activity

  1. krwq commented on Aug 28, 2020

    @krwq
    Member

    @eerhardt one thing to note is that in case of overload without namespace the namespace is ignored. In case of this overload null may mean:

    • expect no namespace (empty namespace) / default namespace
    • ignore namespace and do what IsStartElement(string) would do

    we should figure out how to interpret that and do some research on what customers would expect

  2. KalleOlaviNiemitalo commented on Aug 29, 2020

    @KalleOlaviNiemitalo

    I don't think it should treat string localname (local name) as string name (qualified name) just because string ns is null.

    If I'm writing an XML deserializer that should compare expanded names regardless of which namespace prefix is used, then I should avoid IsStartElement(string name) and instead use IsStartElement(string localname, string ns). But if ns == null causes the latter to behave like the former, then it will be harder for me to be sure I did it right. I don't think there is a scenario in which the caller of IsStartElement would want a runtime decision on whether to use Namespaces in XML semantics or not.

    So, for IsStartElement(localname, ns: null), my order of preference would be:

    1. Return false regardless of localName -- current implementation, no compatibility risk, easy to document
    2. Throw ArgumentNullException -- consistent with XNamespace.GetName, but would be a breaking change
    3. Same as IsStartElement(localName, ns: string.Empty) -- seems inconsistent with existing APIs
    4. Same as IsStartElement(name: localName) -- does not seem useful; consistent with undocumented behavior of XmlWriter.WriteStartElement(string localName, string ns)

    If the treatment of string ns in XmlReader.IsStartElement is changed, then XmlReader.ReadStartElement should be changed similarly.

  3. added this to the Future milestone on Aug 31, 2020
  4. krwq commented on Nov 19, 2020

    @krwq
    Member

    @eerhardt I generally agree with @KalleOlaviNiemitalo + what I wrote above, I'm leaning toward closing this as "won't fix" given the confusion this would cause. Please re-open if you feel strongly about fixing this.

  5. ghost locked as resolved and limited conversation to collaborators on Dec 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.Xml

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions