XmlReader继承并省略重复的命名空间

时间:2015-12-15 09:36:32

标签: c# xml xml-namespaces xmlreader

我已经实现了XmlReader类继承者。我的新类提供了一个xml数据,例如:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="" />
    <child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="" />
</root>

问题是一个名称空间声明多次重复。导致此命名空间声明是因为当读者达到“type”属性时,其属性具有以下值:LocalName =“type”,Prefix =“xsi”和NamespaceURI =“{{ 3}}”。我想通过在“root”节点中声明napespace来防止这种重复。有可能吗?

以下是我的代码示例:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace Test
{
    internal class Node
    {
        public string LocalName;

        public string Prefix;

        public string NamespaceURI;

        public string Value;

        public XmlNodeType NodeType;
    }

    public class MyXmlReader : XmlReader
    {
        private readonly Queue<Node> _data;

        private string _localName;
        private string _prefix;
        private string _namespaceURI;
        private string _value;
        private XmlNodeType _nodeType;
        private ReadState _readState;

        public MyXmlReader()
        {
            _data = new Queue<Node>();

            _data.Enqueue(new Node { LocalName = "root", NodeType = XmlNodeType.Element });

            _data.Enqueue(new Node { LocalName = "child", NodeType = XmlNodeType.Element });
            _data.Enqueue(new Node
            {
                LocalName = "type",
                Prefix = "xsi",
                NamespaceURI = "http://www.w3.org/2001/XMLSchema-instance",
                NodeType = XmlNodeType.Attribute
            });

            _data.Enqueue(new Node { LocalName = "child", NodeType = XmlNodeType.Element });
            _data.Enqueue(new Node
            {
                LocalName = "type",
                Prefix = "xsi",
                NamespaceURI = "http://www.w3.org/2001/XMLSchema-instance",
                NodeType = XmlNodeType.Attribute
            });

            _data.Enqueue(new Node { NodeType = XmlNodeType.EndElement });

            _readState = ReadState.Initial;
        }

        public override bool Read()
        {
            if (_data.Count > 0)
            {
                Node node = _data.Dequeue();

                _localName = node.LocalName;
                _prefix = node.Prefix;
                _namespaceURI = node.NamespaceURI;
                _value = node.Value;
                _nodeType = node.NodeType;

                return true;
            }

            return false;
        }

        public override void Close()
        {
            _readState = ReadState.Closed;
        }

        public override bool MoveToFirstAttribute()
        {
            return MoveToNextAttribute();
        }

        public override bool MoveToNextAttribute()
        {
            if (_data.Peek().NodeType == XmlNodeType.Attribute)
                return Read();

            return false;
        }

        public override bool MoveToElement()
        {
            _nodeType = XmlNodeType.Element;
            _localName = "child";

            return true;
        }

        public override bool ReadAttributeValue()
        {
            return false;
        }

        public override XmlNodeType NodeType
        {
            get { return _nodeType; }
        }

        public override string LocalName
        {
            get { return _localName; }
        }

        public override string NamespaceURI
        {
            get { return _namespaceURI; }
        }

        public override string Prefix
        {
            get { return _prefix; }
        }

        public override string Value
        {
            get { return _value; }
        }

        public override string BaseURI
        {
            get { return "Test"; }
        }

        public override bool IsEmptyElement
        {
            get 
            { 
                if (_localName == "root")
                    return false;

                return true;
            }
        }

        public override ReadState ReadState 
        {
            get { return _readState; }
        }

        public override bool EOF
        {
            get { throw new NotImplementedException(); }
        }

        public override int Depth
        {
            get { throw new NotImplementedException(); }
        }

        public override string GetAttribute(string name)
        {
            throw new NotImplementedException();
        }

        public override string GetAttribute(string name, string namespaceURI)
        {
            throw new NotImplementedException();
        }

        public override string GetAttribute(int i)
        {
            throw new NotImplementedException();
        }

        public override bool MoveToAttribute(string name)
        {
            throw new NotImplementedException();
        }

        public override bool MoveToAttribute(string name, string ns)
        {
            throw new NotImplementedException();
        }

        public override string LookupNamespace(string prefix)
        {
            throw new NotImplementedException();
        }

        public override void ResolveEntity()
        {
            throw new NotImplementedException();
        }

        public override int AttributeCount
        {
            get { throw new NotImplementedException(); }
        }

        public override XmlNameTable NameTable
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class Program
    {
        public static void Main()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(new MyXmlReader());
            return;
        }
    }
}

我知道一些讨厌且棘手的方法:在xsi名称空间中为root生成一些假属性。然后xml数据看起来像

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:fake="fake">

但我也有XSD验证,这种方法对我来说不适合(没有“假”attr的定义)

0 个答案:

没有答案