从System.Xml.XmlReader中获取当前行号 (C# & .Net)

26

有人知道如何获取System.Xml.XmlReader的当前行号吗?我试图记录在文件中找到Xml元素的位置。

2个回答

46

利用由XmlReader支持的IXmlLineInfo接口:

IXmlLineInfo xmlInfo = (IXmlLineInfo)reader;
int lineNumber = xmlInfo.LineNumber;

4
看起来是一种不好的做法。由于XmlReader没有继承IXmlLineInfo,因此实现此抽象类的实现可能不会实现该接口。需要检查是否支持该接口。 - SerG
1
请使用IXmlLineInfo xmlInfo = reader as IXmlLineInfo; 这是良好的代码实践。@shuvra - Shuvra
1
我可以确认@SerG的评论,因为XmlNodeReader没有继承IXmlLineInfo - Josef Trejbal
从那里得到了一个不错的null。因此这取决于您获得了哪个XmlReader实现。不安全。 - David Burg
如果 LineNumber 或 LinePosition 超过 32 位有符号整数的最大值怎么办?是的,这是我目前遇到的问题。 - Peter

3
扩展IXmlLineInfo接口的文档非常糟糕。通过一些调查,我可以告诉你以下内容:
1)System.Xml.XmlReader是抽象的,因此您永远不会处理这个实例,因此它没有实现IXmlLineInfo并不是非常令人担心(尽管如果它实现了,一切都会变得更加容易 :))
2)System.Xml.IXmlLineInfo接口提供两个属性:LineNumberLinePosition(这是我们关心的内容),以及一个方法:HasLineInfo(),根据文档,它可以让您知道实现者是否能够返回行信息。
3)在System.Xml.XmlReader的继承者中,我们有:
System.Xml.XmlDictionaryReader - abstract, used by WCF for serialization, no IXmlLineInfo
System.Xml.XmlNodeReader - used when reading a node, no IXmlLineInfo
System.Xml.XmlTextReader - used when reading a stream of data, has IXmlLineInfo
System.Xml.XmlValidatingReader - used when reading a stream of data and validating, has IXmlLineInfo.

看上面的列表,XmlDictionaryReader 将在内部使用,当您传递要读取的节点时,将使用 XmlNodeReader(因为已解析的节点已经与其源文档分离),当您从文档中读取时将使用 XmlTextReaderXmlValidtingReader(均实现 IXmlLineInfo)。 因此,长话短说,如果可能或有用提供位置信息,则框架会这样做。
话虽如此,文档似乎非常简洁。 刚刚完成此操作后,我所做的是(其中 _xr 是 System.Xml.XmlReader 的未知具体实现):
string position = "(unknown)";
    if (_xr != null && typeof(System.Xml.IXmlLineInfo).IsInstanceOfType(_xr) &&
((System.Xml.IXmlLineInfo)_xr).HasLineInfo())
    {
        System.Xml.IXmlLineInfo li = (System.Xml.IXmlLineInfo)_xr;
        position = "(" + li.LineNumber.ToString() + "," + li.LinePosition.ToString() + ")";
    }

所有这些都说完,当我实际运行上面的代码时,_xr 的类型最终变成了System.Xml.XsdValidatingReader(祝你好运找到相关文档!),它继承自System.Xml.XmlReader,但不继承自System.Xml.XmlValidatingReaderSystem.Xml.XmlTextReader。因此,像上面那样使用一个方法可能是明智的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接