XML账单通常有一个返回和解析的Node。我们遇到过一个XML账单有多个节点的问题。由于代码未设置为处理该代码,因此客户最终收到了错误的账单。
这是我通过账单清单的代码。如果它返回一个节点,那么它将解析来自xml的信息。
var response = new List<CustomerBill>();
try
{
foreach (GetBillForCAResponse eBillResponse in eBillResponseList)
{
var statementDetailsResponse = GetStatementDetails(
new GetStatementDetailsRequest
{
BatchId = eBillResponse.BatchId,
CustomerAccountId = eBillResponse.CA.ToString("000000000"),
StatementId = eBillResponse.CAS_NUM.ToString("0000")
});
string xmlBill = statementDetailsResponse.StatementAsXML.ToString();
var document = new XmlDocument();
document.LoadXml(xmlBill);
var saDetailedPageNode = XmlBillParser.GetDetailPageSectionBySa(requestSa, xmlBill);
if (saDetailedPageNode == null) continue;
var customerBill = new CustomerBill();
customerBill.IsSurepay = XmlBillParser.GetSurepayFlagFromBill(document);
customerBill.ServiceAddress = XmlBillParser.GetServiceAddress(requestSa, document);
customerBill.monthName = XmlBillParser.GetnillStatementDate(requestSa, xmlBill);
customerBill.EqCurlPlanBal = XmlBillParser.getEqualizerCurrentPlanBalance(document);
customerBill.EqPymntDue = XmlBillParser.getEqualizerPaymentDue(document);
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSa, xmlBill, saDetailedPageNode);
response.Add(customerBill);
}
}
catch (Exception ex)
{
trace.Write(new InvalidOperationException(requestSa, ex));
}
return response;
}
以下是检查XML中是否存在节点的方法。我已经更改了代码,以便返回所有节点。我不得不将类型xmlNode更改为xmlNodeList,因为它现在返回一组节点。 ****这是什么导致我的代码在其他地方的所有问题。***
public static xmlNode GetDetailPageSectionBySa(string sa, string statementXml)
{
XmlDocument document = new XmlDocument();
document.LoadXml(statementXml);
string requestSa = sa.PadLeft(9, '0');
string xpath = String.Format("//Para[IRBILGP_SA_SAA_ID_PRINT.SERVICE.ACCOUNT.STATMENT='{0}S{1}']/..", requestSa.Substring(0, 4), requestSa.Substring(4));
return document.SelectNodes(xpath);
//var nodes = document.SelectNodes(xpath);
// if(nodes.Count > 0) return nodes[nodes.Count - 1];
//if(!SaExistInBill(requestSa, statementXml)) return null;
//var node = GetDetailPageSectionByBillPrisminfoIndex(sa, statementXml);
//if (node != null) return node;
//return null;
}
所以回到它被称为的地方..我在这里得到一个无效的争论
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSA, xmlBill, saDetailedPageNode);
,因为参数saDetailedPageNode
现在是xmlNodeList
时,预计类型为xmlNode
。如果我转到我在此代码末尾添加的方法private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(string requestSA, string xmlBill, XmlNode detailPageNode)
,您可以看到。如果我将参数XmlNode detailPageNode
更改为XmlNodeList detailPageNode
,我必须修复上面的无效争议,我认为detailPageNode.SelectNodes
无效,因为xmlNodeList
没有{{1}作为扩展方法。我通过这种方法大量使用这种扩展方法。所以我遇到了很多错误。
SelectNodes
如何修复无效参数,以便我可以使用xmlNodeList而不是xmlNode?有没有办法转换或演员?或者我可以使用另一个xml对象吗?
因为我现在正在返回多个节点。我知道我需要遍历 var saDetailedPageNode = XmlBillParser.GetDetailPageSectionBySa(requestSa, xmlBill);
if (saDetailedPageNode == null) continue;
var customerBill = new CustomerBill();
customerBill.IsSurepay = XmlBillParser.GetSurepayFlagFromBill(document);
customerBill.ServiceAddress = XmlBillParser.GetServiceAddress(requestSa, document);
customerBill.monthName = XmlBillParser.GetnillStatementDate(requestSa, xmlBill);
customerBill.EqCurlPlanBal = XmlBillParser.getEqualizerCurrentPlanBalance(document);
customerBill.EqPymntDue = XmlBillParser.getEqualizerPaymentDue(document);
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSa, xmlBill, saDetailedPageNode);
response.Add(customerBill);
}
}
catch (Exception ex)
{
trace.Write(new InvalidOperationException(requestSa, ex));
}
return response;
}
private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(string requestSA, string xmlBill, XmlNode detailPageNode)
{
var saBillDetail = new ServiceAddressBillDetail();
saBillDetail.UsageServiceName = requestSA;
var meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_b");
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_a");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_b");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_a");
}
var demandXMLNodes = detailPageNode.SelectNodes("Usage_kW_Total_Bold");
部分。如果不为每个节点创建新帐单,我该怎么做?一个xml中的所有节点都需要包含在一个帐单中。
答案 0 :(得分:0)
很难看到发生了什么,但这可能是问题;
string xpath = String.Format("//Para..
“//”将搜索整个文档,但您可能希望搜索后代元素。
这是一些处理类似问题的代码;
XmlNodeList staffNodes = resultXML.SelectNodes("//staff");
List<TempStaff> tempStaffs = staffNodes
.Cast<XmlNode>()
.Select(
i =>
new TempStaff()
{
StaffId = i.SelectSingleNode("id").InnerText,
Forename = i.SelectSingleNode("forename").InnerText,
Surname = i.SelectSingleNode("surname").InnerText,
}
).ToList();
我的XML看起来像
<staff><forename>asdf</forename><surname>ddsf</surname><id>123</id>... </staff>
<staff><forename>asdfas</forename><surname>asffdf</surname><id>456</id>...</staff>
答案 1 :(得分:0)
根据您提供的代码,XmlNodeList
的重构需要考虑的唯一部分是GetServiceAccountUsageAndBillingDetail()
,因此您有两种选择:
GetServiceAccountUsageAndBillingDetail()
以获取XmlNodeList
参数,并汇总该方法中的值以提供最终的ServiceAddressBillDetail
对象。XmlNode
中的XmlNodeList
个对象,并自行协调不同的ServiceAddressBillDetail
个对象。 如果没有ServiceAddressBillDetail
的详细信息,我只能猜测哪个更好,但我建议使用第一个选项。
private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(
string requestSA,
string xmlBill,
XmlNodeList detailPageNodes)
{
var saBillDetail = new ServiceAddressBillDetail();
saBillDetail.UsageServiceName = requestSA;
foreach(XmlNode detailPageNode in detailPageNodes)
{
var meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_b");
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_a");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_b");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_a");
}
var demandXMLNodes = detailPageNode.SelectNodes("Usage_kW_Total_Bold");
//Whatever comes next
}
}
假设ServiceAddressBillDetail
具有“使用”属性,您只需将每个detailPageNode
中的相应值添加到saBillDetail
对象。