使用缺少属性的元素验证 XSD 上的 XML

问题描述 投票:0回答:1

我的问题有两个:当属性丢失时,确定行号以及该属性属于哪个元素。

我通过在 XDocument 创建中添加适当的选项来解决第一部分:

// create XDocument
var opts = LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo;
XDocument xDocument = XDocument.Parse(stringWriter.ToString(), opts);

现在我读入 XSD 并验证:

// Read in the XSD
string schema = File.ReadAllText("c:\myschema.xsd");
XmlSchemaSet xmlSchemaSet = new();
xmlSchemaSet.Add("http://www.company.com/Import/v1_9", XmlReader.Create(new StringReader(schema)));

// Validate the XML against the XSD            
xDocument.Validate(xmlSchemaSet, (sender, ex) =>
{
    string validationErr = string.Format($"XML Parse Error: Severity={ex.Severity} Line={ex.Exception.LineNumber} Position={ex.Exception.LinePosition}");
    Debug.Print("validationErr: {0}", validationErr);
    validationErr = string.Format($"Message={ex.Exception}");
    Debug.Print("validationErr: {0}", validationErr);
}, true);

我的 XML 具有已知缺失的属性,会导致此输出进行调试:

validationErr: XML Parse Error: Severity=Error Line=436 Position=26
Message: System.Xml.Schema.XmlSchemaValidationException: The required attribute 'Desc' is missing. 

这太棒了。我现在知道发生此错误的行和位置。除此之外,我想知道包含此错误的元素的完整路径。现在它只说属性“描述”丢失了。嗯,我可能有超过 15 个不同的元素类型具有该属性。这是我知道发生此错误的部分节点:

<Roads Count="1">
      <Road Num="1" Width="168" Distance="19388" Unit="FT">
        <Ident RecordId="" />     <<--- the Desc attribute goes here
        <Notes />
      </Road>
</Roads>

今天早上我一直在寻找一种打印类似内容的方法: The required attribute 'Desc' is Missing in Root 颂歌1 奥德2 ode3\道路\道路\标识。这比行号和位置更能帮助人们更好地查看它。尽管我们最终会同时使用两者,但完整路径会立即告诉我们在 SQL 数据库中的何处查找缺失值。那么有什么方法可以获取错误发生位置的更详细信息和路径吗?

xml validation xpath xsd attributes
1个回答
0
投票

你还没有说你是否准备使用不同的模式验证器来满足这个要求(事实上,你还没有说你正在使用哪个模式验证器,但我想我可以解决它)。

如果您使用 Saxon 模式验证器 [我公司的产品],则缺少属性的标准错误消息将如下所示:

Validation error on line 89 column 29 of books.xml:
  FORG0001: Required attribute @Q{}DESC is missing on element <CATEGORY>
  See https://www.w3.org/TR/xmlschema11-1/#cvc-complex-type clause 4

因此它会为您提供缺少属性的元素名称。

此外,如果您提供自己的

InvalidityHandler
,它将使用
Invalidity
对象进行调用,该对象包含一个
AbsolutePath
属性,给出发现无效的元素的路径(元素名称和位置)。在我的示例中,
AbsolutePath
显示为

/Q{}BOOKLIST[1]/Q{}CATEGORIES[1]/Q{}CATEGORY[4]

尽管同样的信息也可以以其他格式提供。

© www.soinside.com 2019 - 2024. All rights reserved.