代码之家  ›  专栏  ›  技术社区  ›  Matt Mitchell

使用XPath实现IXmlSerializable ReadXml()的最佳方法

  •  2
  • Matt Mitchell  · 技术社区  · 15 年前

    我正在实现IXmlSerializable的ReadXml()方法,我认为使用XPath可能是最好的方法。

    但是,ReadXml()需要正确处理读取器位置。

    因此,考虑到我的WriteXml()生成如下内容:

    <ObjectName>
      <SubNode>2</SubNode>
      <SubNode>2</SubNode>
    </ObjectName>
    

    public override void ReadXml(System.Xml.XmlReader reader)
    {
            reader.Read(); /* Read Opening tag */
            /* Using reader.ReadStartElement("ObjectName") reads forward a node,
               i.e. current node becomes the first <SubNode>
               whereas Read() doesn't even when the documentation says they both do 
            */
            XPathNavigator n = MakeXPathNavigator(reader.ReadSubtree());
            XPathNodeIterator nodes = n.Select(".//SubNode");
            while (nodes.MoveNext())
            {
                /* Do stuff with nodes */
                _values.Add(nodes.Current.ValueAsInt);
            }
            reader.Skip(); /* Skip reader forward */
    }
    
    public static XPathNavigator MakeXPathNavigator(XmlReader reader)
    {
        try
        {
            return new XPathDocument(reader).CreateNavigator();
        }
        catch(XmlException e)
        {
            throw e; /* Maybe hide/deal with exception */
        }
    }
    
    1 回复  |  直到 15 年前
        1
  •  2
  •   Marc Gravell    15 年前

    我怀疑如果经常使用这种方法,您可能会遇到一些性能问题。由于您的xml相对简单,我强烈怀疑您仅使用 XmlReader 直接地

    ……但这样做并不容易;在国际海事组织看来,最好是尽量避免执行 IXmlSerializable (juts使用常规集合属性等)-这是导致bug和挫折的常见原因。