You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XML验证失败时如何提取父节点属性信息(C#实现)

问题:XML Schema验证失败时提取父节点属性信息

我需要编写C#代码,在XML Schema验证失败时提取属性信息。当前代码能定位到具体错误属性(比如提示“'unitCost'属性无效,空字符串不是有效的Decimal值”),但无法获取父节点的orderNumber、Lot、Sequence等属性信息,求解决方法。

XML示例

<Payload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlVersion="1.0" createDate="2023-11-07T14:23:08" messageType="TEST">
    <Orders>
        <OrderHeader resultsIndicator="F" orderNumber="2000100"...>
            <OrderDetail resultsIndicator="F" lot="1234" sequence="01"...>
                <OrderCostingDetail expenseCode="ADMIN"... unitCost="".../>
            </OrderDetail>
        </OrderHeader>
    </Orders>
</Payload>

现有代码

private static void PerformValidation(XmlTextReader xmlTextReader, XmlSchemaSet schemas)
{
    if (schemas == null)
    {
        throw new ArgumentNullException("schemas");
    }

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas = schemas;
    settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;

    string chkatt = string.Empty;

    using (XmlReader reader = XmlReader.Create(xmlTextReader, settings))
    {
        try
        {
            do
            {
                chkatt = string.Concat("orderNo.: ",reader.GetAttribute("orderNumber"), ", Lot:", reader.GetAttribute("lot"), ", Seq:", reader.GetAttribute("sequence"));
            } while (reader.Read());
        }
        catch(Exception ex)
        {
            string error = ex.Message.ToString() + chkatt;
        }
        finally
        {
            reader.Close();   
        }
    }
}

解决方案

原代码的问题在于:验证错误抛出异常时,XmlReader停在错误节点,无法回溯获取父节点属性;且chkatt仅保存最后一次读取的节点属性,并非错误发生时的上下文信息。正确的做法是通过ValidationEventHandler处理验证错误,并在读取XML时跟踪父节点的属性状态。

修改后的代码

private static void PerformValidation(XmlTextReader xmlTextReader, XmlSchemaSet schemas)
{
    if (schemas == null)
    {
        throw new ArgumentNullException("schemas");
    }

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas = schemas;
    settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;

    // 跟踪当前上下文的父节点属性
    string currentOrderNumber = null;
    string currentLot = null;
    string currentSequence = null;

    // 注册验证事件处理器,错误发生时立即处理
    settings.ValidationEventHandler += (sender, e) =>
    {
        string errorContext = $"orderNo.: {currentOrderNumber}, Lot: {currentLot}, Seq: {currentSequence}";
        string fullError = $"{e.Message} | 上下文信息:{errorContext}";
        // 这里可以根据需求记录错误到日志或集合中
        Console.WriteLine(fullError);
    };

    using (XmlReader reader = XmlReader.Create(xmlTextReader, settings))
    {
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    // 遇到目标节点时记录属性值
                    if (reader.Name == "OrderHeader")
                    {
                        currentOrderNumber = reader.GetAttribute("orderNumber");
                    }
                    else if (reader.Name == "OrderDetail")
                    {
                        currentLot = reader.GetAttribute("lot");
                        currentSequence = reader.GetAttribute("sequence");
                    }
                    break;
                case XmlNodeType.EndElement:
                    // 离开节点时清空对应属性,避免上下文混乱
                    if (reader.Name == "OrderHeader")
                    {
                        currentOrderNumber = null;
                    }
                    else if (reader.Name == "OrderDetail")
                    {
                        currentLot = null;
                        currentSequence = null;
                    }
                    break;
            }
        }
    }
}

关键说明

  1. ValidationEventHandler:替代try-catch捕获异常,能在验证错误发生时立即触发,保留当前的XML读取上下文。
  2. 上下文跟踪:通过读取元素的开始/结束节点,维护当前有效的orderNumber、lot、sequence值,确保错误发生时能获取到对应的父节点属性。
  3. 避免回溯:XmlReader是向前只读的,无法直接获取父节点属性,因此必须在读取过程中主动记录上下文信息。

内容的提问来源于stack exchange,提问作者Sheva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:36:04