我正在尝试使用Xml Schema和XDocument.Validate扩展方法验证Xml片段。每当使用无效的Xml片段时,ValidationEventHandler都会正确触发,但XmlSchemaValidationException的LineNumber和LinePosition属性都是0。
private bool Validate(XDocument doc)
{
bool isValid = true;
List<string> validationErrors = new List<string>();
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, "MyCustomSchema.xsd");
doc.Validate(schemas, (sender, args) =>
{
validationErrors.Add(String.Format("{0}: {1} [Ln {2} Col {3}]",
args.Severity,
args.Exception.Message,
args.Exception.LineNumber,
args.Exception.LinePosition));
isValid = false;
}, false);
return isValid;
}
我在上面的示例中的目标是使用validationErrors通知用户验证失败的原因。但是,使用此方法时,LineNumber和LinePosition都为0。
该代码段似乎很简单,并且在验证有效和无效的Xml片段方面似乎按预期工作。
提前致谢!
答案 0 :(得分:5)
您不再验证Xml的文本表示形式,而是验证对象模型。因此,没有行和位置,因为内存中没有文件,但XElement,XAttribute等对象。另一个有用的提示是问自己 - 如果在加载XDocument之后但在运行验证之前修改了(例如添加了elelment),应该返回什么行和位置? 如果您没有创建或修改Xml,最快的方法是使用XmlReader来验证您的Xml文档。作为奖励 - 如果输入是文件或流 - 您应该在验证错误的情况下获得行和位置信息。
答案 1 :(得分:1)
在您的ValidationEventHandler
中,sender
实现了IXmlLineInfo
接口,该接口包含成员System.Xml.IXmlLineInfo.LineNumber
和System.Xml.IXmlLineInfo.LinePosition
所以您可以这样做:
doc.Validate(schemas, (sender, args) =>
{
var lineInfo = sender as IXmlLineInfo;
validationErrors.Add(String.Format("{0}: {1} [Ln {2} Col {3}]",
args.Severity,
args.Exception.Message,
lineInfo?.LineNumber,
lineInfo?.LinePosition));
isValid = false;
}, false);