在 C 中验证后,无法从 XmlReader 中检索属性名称/值#

Unable to retrieve attribute names/values from XmlReader after validation in C#

提问人:Sheva 提问时间:11/9/2023 最后编辑:marc_sSheva 更新时间:11/9/2023 访问量:39

问:

当验证失败时,我需要编写一个 c# 代码以从 XML 中提取属性信息。我下面的代码能够为我提供未通过验证的确切属性,但我还需要从父节点中存在的属性中获得其他信息。

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" orderStatus="FIN" latestShipDate="4/23/2023 12:00:00 AM" cusNumber="791053" cusName="Apple, Ms.Rose" deliveryTerms="HOME" paymentType="AMEX" Destination="TX">
            <OrderDetail resultsIndicator="F" lot="1234" sequence="01" invoice="FGD123401" finalDestination="75013" resultsMessage="DELIVERED" brandNumber="100141" brandName="LG">
<OrderCostingDetail expenseCode="ADMIN" expenseCategory="ADM" rate="2499.50" indicator="F" qualifier="SALE" unitCost="2499.50" level="002"/>
                <OrderCostingDetail expenseCode="ADMIN" expenseCategory="ADM" rate="125.00" indicator="F" qualifier="SALE" unitCost="" level="002"/>
                <OrderCostingDetail expenseCode="ADMIN" expenseCategory="ADM" rate="5879.20" indicator="F" qualifier="SALE" unitCost="5879.20" level="002"/>
            </OrderDetail>
        </OrderHeader>
        <OrderHeader resultsIndicator="I" orderNumber="2000101" orderStatus="INIT" latestShipDate="12/10/2023 12:00:00 AM" cusNumber="56782" cusName="Roy, Mr.Ralph" deliveryTerms="HOME" paymentType="VISA" Destination="TX">
            <OrderDetail resultsIndicator="I" lot="1234" sequence="01" invoice="FGD123401" finalDestination="75013" resultsMessage="DELIVERED" brandNumber="100141" brandName="LG">
                <OrderCostingDetail expenseCode="ADMIN" expenseCategory="ADM" rate="24.00" indicator="I" qualifier="SALE" unitCost="24.00" level="004"/>
            </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; //sarul1
    // settings.ValidationEventHandler += (sender, args) => error = ValidationCallback(sender, args);

    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();   
        }
    }
}

我在主函数中调用上述方法,以根据预定义的架构验证是否有任何 NULL 字段。我收到错误

“unitCost”属性无效...字符串 '' 不是有效的 Decimal 值

我需要将其他属性信息(如orderNumber,Lot和Sequence)添加到此消息中(在本例中:orderNumber = 2000100,Lot = 1234,Seq = 01),我无法使用此代码执行此操作。

请帮我前进!

C XML C#-4.0 XmlReader

评论


答:

1赞 Mohammed Swillam 11/9/2023 #1

该函数在错误消息中缺少上下文,因为它没有跟踪父节点中的属性值。PerformValidation

请考虑以下更新的代码:

private static void PerformValidation(XmlTextReader xmlTextReader, XmlSchemaSet schemas)

{ if (schemas == null) { 抛出新的 ArgumentNullException(“schemas”); }

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

string orderNumber = string.Empty;
string lot = string.Empty;
string sequence = string.Empty;

using (XmlReader reader = XmlReader.Create(xmlTextReader, settings))
{
    try
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                if (reader.Name == "OrderHeader")
                {
                    orderNumber = reader.GetAttribute("orderNumber");
                }
                else if (reader.Name == "OrderDetail")
                {
                    lot = reader.GetAttribute("lot");
                    sequence = reader.GetAttribute("sequence");
                }
            }
            else if (reader.NodeType == XmlNodeType.Attribute && reader.Value == string.Empty)
            {
                string errorMessage = $"Validation error in OrderNo.: {orderNumber}, Lot: {lot}, Seq: {sequence}. ";
                
                // Handle or log the error message as needed
                Console.WriteLine(errorMessage);
            }
        }
    }
    catch (Exception ex)
    {
        string error = ex.Message.ToString();
        // Handle or log the exception as needed
        Console.WriteLine(error);
    }
    finally
    {
        reader.Close();
    }
}

}

此代码引入了变量(orderNumber、lot 和 sequence)来存储这些值,从而允许在发生验证错误时提供更详细的错误消息。

试一试,如果需要进一步修改,请告诉我。 如果这个答案解决了你的问题,请不要忘记标记为答案。:)