Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么XmlNamespaceManager为HasNamespace返回不一致的结果?_C#_Xml_Xmlreader - Fatal编程技术网

C# 为什么XmlNamespaceManager为HasNamespace返回不一致的结果?

C# 为什么XmlNamespaceManager为HasNamespace返回不一致的结果?,c#,xml,xmlreader,C#,Xml,Xmlreader,我试图处理一个XML文档并确定其中定义了哪些名称空间,但从XmlNamespaceManager.HasNamespace获得一致的结果时遇到了问题。当它读取文档时,HasNamespace将返回false,即使它仍然声明并在范围内 示例代码: var ctx = new XmlParserContext(null, new XmlNamespaceManager(new NameTable()), null, XmlSpace.None); var set = new XmlR

我试图处理一个XML文档并确定其中定义了哪些名称空间,但从XmlNamespaceManager.HasNamespace获得一致的结果时遇到了问题。当它读取文档时,HasNamespace将返回false,即使它仍然声明并在范围内

示例代码:

    var ctx = new XmlParserContext(null, new XmlNamespaceManager(new NameTable()), null, XmlSpace.None);
    var set = new XmlReaderSettings() { IgnoreComments = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true };

    using (var xml = new StringReader(
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<rdf:RDF " +
        "  xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"> " +
        "  <rdf:Description rdf:about=\"x\" /> " +
        "</rdf:RDF>"))
    using (var rdr = XmlReader.Create(xml, set, ctx))
    {
        rdr.MoveToContent();

        Console.WriteLine(rdr.Name);
        Console.WriteLine(rdr.LookupNamespace("rdf"));
        Console.WriteLine(ctx.NamespaceManager.HasNamespace("rdf"));    // True
        
        rdr.Read();
        
        Console.WriteLine(rdr.Name);
        Console.WriteLine(rdr.LookupNamespace("rdf"));
        Console.WriteLine(ctx.NamespaceManager.HasNamespace("rdf"));    // False
        
        rdr.Read();
        
        Console.WriteLine(rdr.Name);
        Console.WriteLine(rdr.LookupNamespace("rdf"));
        Console.WriteLine(ctx.NamespaceManager.HasNamespace("rdf"));    // True
    }
var ctx=new-XmlParserContext(null,new-XmlNamespaceManager(new-NameTable()),null,XmlSpace.None);
var set=new XmlReaderSettings(){IgnoreComments=true,IgnoreProcessingInstructions=true,IgnoreWhitespace=true};
使用(var xml=newstringreader)(
"" +
" " +
"   " +
""))
使用(var rdr=XmlReader.Create(xml,set,ctx))
{
rdr.MoveToContent();
Console.WriteLine(rdr.Name);
WriteLine(rdr.LookupNamespace(“rdf”));
Console.WriteLine(ctx.NamespaceManager.HasNamespace(“rdf”);//True
rdr.Read();
Console.WriteLine(rdr.Name);
WriteLine(rdr.LookupNamespace(“rdf”));
Console.WriteLine(ctx.NamespaceManager.HasNamespace(“rdf”);//False
rdr.Read();
Console.WriteLine(rdr.Name);
WriteLine(rdr.LookupNamespace(“rdf”));
Console.WriteLine(ctx.NamespaceManager.HasNamespace(“rdf”);//True
}

当读者输入每个新元素时,它将调用命名空间管理器上的
PushScope
。一旦它离开元素(通过自动关闭标记或相应的结束标记的结尾),它将调用
PopScope

与命名空间管理器的某些其他成员不同,它只回答当前范围的问题

获取一个值,该值指示提供的前缀是否具有为当前推式作用域定义的命名空间

(我的重点)

一般来说,您不应该过多地使用名称空间前缀,除非您实际上是在解析自己,而不是利用现有的工具。它是元素名(
RDF
)和名称空间(
http://www.w3.org/1999/02/22-rdf-syntax-ns#\
)唯一定义元素类型-前缀可以更改(前提是在其有效的文档范围内保持一致)无需更改XML的信息内容


如果创建此类,您可以亲自看到:

class LoggingNamespaceManager : XmlNamespaceManager
{
    public LoggingNamespaceManager (XmlNameTable table) : base(table)
    {

    }

    public override void PushScope()
    {
        Console.WriteLine("Push");
        base.PushScope();
    }

    public override bool PopScope()
    {
        Console.WriteLine("Pop");
        return base.PopScope();
    }
}
并在示例的第一行中实例化它,而不是
XmlNamespaceManager



但请不要这样做。已经有足够多的脆弱的“XML”解析器建立在关于XML的无效假设之上。使用框架中提供的工具,就像您目前所做的那样。

我原以为父级中定义的任何名称空间都会自动流到子级,但我想情况并非如此。至于前缀,这很公平,但我正在使用一个标准来定义必须可用的前缀。