无法访问或查找对 System.Xml.Linq.LineInfoAnnotation 的引用.这是为什么呢?



我有一个应用程序,它接受一个XML文档并按某些属性对其进行排序。我有与 XML 文档的每一行相关联的信息,我想将其包含在排序文档中。为了做到这一点,

当我加载文件时,我确保行信息是使用XDocument.Load(file, LoadOptions.SetLineInfo)加载的。

然后,我递归地遍历每个 XElement 并获取其行信息。当我运行该应用程序时,我注意到每个XElement都有两个注释,

  • 类型之一 System.Xml.Linq.LineInfoAnnotation
  • 类型为System.Xml.Linq.LineInfoEndElementAnnotation

它们包含我需要的信息,但在私人字段中。

我找不到有关这些类的任何信息,无法实例化它们,它们不会出现在System.Xml.Linq下的对象浏览器中。然而它们存在,我可以对它们运行"GetType()"并获取有关该类的信息。

如果它们存在,为什么它们不在 MSDN 引用中,为什么我不能实例化或扩展它们?为什么在对象浏览器中找不到它们?

附言 我的解决方法是使用反射来获取每个元素中包含的信息。但是我仍然无法传递类名来告诉方法它是什么类型,我必须将对象与XElement.Annotations(typeof(object))隔离开来,然后在其上运行GetType()。我在下面对此进行了说明。

public object GetInstanceField(Type type, object instance, string fieldName)
{
//reflective method that gets value of private field
}
XElement xEl = existingXElement;    //existingXElement is passed in
var annotations = xEl.Annotations(typeof(object)); //contains two objects, start and end LineInfoAnnotation
var start = annotations.First(); 
var end = annotations.Last(); 
var startLineNumber = GetInstanceField(start.GetType(), start, lineNumber);  //lineNumber is private field I'm trying to access.
var endLineNumber = GetInstanceField(end.GetType(), end, lineNumber);

这段代码有效,但同样,我不能只告诉方法"typeof(LineInfoAnnotation)",而是必须在现有对象上执行 GetType。我无法理解这一点。

这些类是私有的 - 如果你愿意的话,这是一个实现细节。

所有 XObjects(元素、属性)都实现 IXmlLineInfo 接口 - 但它们显式实现接口,因此您必须执行强制转换才能访问属性。

获得IXmlLineInfo后,您可以使用属性LineNumber和LinePosition。

var data = 
@"<example>
<someElement
someAttribute=""val"">
</someElement></example>
";
var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(data)), LoadOptions.SetLineInfo);
foreach(var element in doc.Descendants()) {
var elLineInfo = element as IXmlLineInfo;
Console.Out.WriteLine(
$"Element '{element.Name}' at {elLineInfo.LineNumber}:{elLineInfo.LinePosition}");

foreach(var attr in element.Attributes()) {
var attrLineInfo = attr as IXmlLineInfo;
Console.Out.WriteLine(
$"Attribute '{attr.Name}' at {attrLineInfo.LineNumber}:{attrLineInfo.LinePosition}");
}
}

输出:

Element 'example' at 1:2
Element 'someElement' at 2:2
Attribute 'someAttribute' at 3:3

要获取 EndElement 信息,您必须使用普通的旧 XML 读取器,因为 XObject api 不会公开有关元素结束位置的任何信息。

using(var reader = doc.CreateReader()) {    
while(reader.Read()) {
var lineInfo = reader as IXmlLineInfo;
Console.Out.WriteLine($"{reader.NodeType} {reader.Name} at {lineInfo.LineNumber}:{lineInfo.LinePosition}");
if(reader.NodeType == XmlNodeType.Element && reader.HasAttributes) {
while(reader.MoveToNextAttribute()) {
Console.Out.WriteLine($"{reader.NodeType} {reader.Name} at {lineInfo.LineNumber}:{lineInfo.LinePosition}");
}
}
}   
}

输出:

Element example at 1:2
Element someElement at 2:2
Attribute someAttribute at 3:3
EndElement someElement at 5:5
EndElement example at 5:19

相关内容

  • 没有找到相关文章