代码之家  ›  专栏  ›  技术社区  ›  Courtney Wright

如何在不读取C的情况下检查xml中是否存在另一个节点#

  •  2
  • Courtney Wright  · 技术社区  · 9 年前

    private Task<List<TAxEntity>> Deserialize(XmlReader reader)
        {
            var deserializer = new XmlSerializer(typeof(TAxEntity));
            var entities = new List<TAxEntity>();
    
            do
            {
                using (var stringReader = new StringReader(reader.ReadOuterXml()))
                {
                    var entity = (TAxEntity)deserializer.Deserialize(stringReader);
    
                    entities.Add(entity);
                }
            }
            while (reader.ReadToNextSibling(EntityElementName));
    
            return Task.FromResult(entities);
        }
    
    1 回复  |  直到 9 年前
        1
  •  0
  •   dbc    9 年前

    XmlReader 已正确定位,您可以检查 reader.NodeType == XmlNodeType.Element 和 reader.Name == EntityElementName 。然后,如果读卡器已正确定位,请不要使用 ReadToNextSibling() .

    1. 而不是检查正确的 reader.Name LocalName 和 NamespaceURI reader.ReadToNextSibling(string localName,string namespaceURI) bug to be avoided

    2. 而不是 ReadOuterXml() 呼叫 reader.ReadSubtree() 并将返回的读取器直接传递给 deserializer.Deserialize() ReadSubtree() 允许 XmlSerializer 直接从传入的

    综上所述,您可以引入以下低级扩展方法:

    public static class XmlReaderExtensions
    {
        public static IEnumerable<TElement> DeserializeSequence<TElement>(this XmlReader reader, string localEntityElementName, string namespaceURI)
        {
            if (reader == null)
                throw new ArgumentNullException();
            var deserializer = new XmlSerializer(typeof(TElement));
            while ((reader.NodeType == XmlNodeType.Element && reader.LocalName == localEntityElementName && reader.NamespaceURI == namespaceURI)
                || reader.ReadToNextSibling(localEntityElementName, namespaceURI))
            {
                // Using ReadSubtree instead of ReadOuterXml() avoids having do parse, reformat, then parse the formatted XML a second time
                // by reading directly from the current stream only once.
                TElement element;
                using (var subReader = reader.ReadSubtree())
                {
                    element = (TElement)deserializer.Deserialize(subReader);
                }
                // Consume the EndElement also (or move past the current element if reader.IsEmptyElement).
                reader.Read();
                yield return element;
            }
        }
    }
    

    Deserialize() 方法如下:

        private Task<List<TAxEntity>> Deserialize(XmlReader reader)
        {
            var entities = reader.DeserializeSequence<TAxEntity>(EntityElementName, "" /* Pass the correct namespace here */).ToList();
    
            return Task.FromResult(entities);
        }       
    

    .Net fiddle .

    请注意,任何手册 代码应该使用缩进和未缩进的XML进行单元测试,因为在解析缩进的XML时,涉及跳过节点的错误有时会被掩盖(因为会跳过空白节点)