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

无法读取XML中Transaction元素及子节点,获取节点返回Null

问题解决:XmlDocument读取多命名空间XML节点返回Null的问题

核心原因分析

你的XML存在两个不同的默认命名空间,且XPath路径错误、代码存在拼写/语法问题,导致节点查找失败:

  • 根节点RetailTransactionLogDirectInsertRequest的默认命名空间:http://retalix.com/R10/services
  • Transaction节点及内部所有子节点的默认命名空间:http://www.nrf-arts.org/IXRetail/namespace/
    你仅注册了根节点的命名空间,未处理Transaction节点的命名空间,导致其内部子节点无法被定位。

修正后的完整代码

using System.Reflection;
using System.Xml;

Assembly asmbly = Assembly.GetExecutingAssembly();
XmlDocument xDoc = new XmlDocument();
xDoc.Load(asmbly.GetManifestResourceStream("DaxWebServiceLib.sales.xml"));

// 注册两个命名空间:根节点的ns,Transaction节点的ix
XmlNamespaceManager xnsmgr = new XmlNamespaceManager(xDoc.NameTable);
xnsmgr.AddNamespace("ns", "http://retalix.com/R10/services");
xnsmgr.AddNamespace("ix", "http://www.nrf-arts.org/IXRetail/namespace/");

// 正确的XPath路径:根 -> POSLog -> Transaction(ix命名空间) -> 子节点
XmlElement xeWorkstationID = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:WorkstationID", xnsmgr);
xeWorkstationID.InnerText = "0001";

XmlElement xeDS = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:WorkstationID", xnsmgr);
xeDS.InnerText = storeNum + "0001";

XmlElement xeseq = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:SequenceNumber", xnsmgr);
xeseq.InnerText = sequenceNo;

XmlElement xeCD = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:TransactionID", xnsmgr);
xeCD.InnerText = _sessiontoken;

// 定位RetailTransaction下的子节点,全部使用ix命名空间
XmlElement xeCD1 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:Sale/ix:POSIdentity/ix:POSItemID", xnsmgr);
xeCD1.InnerText = UPC;

XmlElement xeCD2 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:Sale/ix:ItemID", xnsmgr);
xeCD2.InnerText = UPC; // 修正拼写错误:eCD2 -> xeCD2

XmlElement xeCD3 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:Sale/ix:Quantity", xnsmgr);
xeCD3.InnerText = quanity;

XmlElement xeCD4 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:ScanData", xnsmgr);
xeCD4.InnerText = UPC;

XmlElement xeCD5 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:SequenceNumber", xnsmgr);
xeCD5.InnerText = sequenceNo;

XmlElement xeCD6 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:BeginDateTime", xnsmgr);
xeCD6.InnerText = SalesDTime;

XmlElement xeCD7 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:RetailTransaction/ix:LineItem/ix:EndDateTime", xnsmgr);
xeCD7.InnerText = SalesDTime;

XmlElement xeCD8 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:BusinessDayDate", xnsmgr);
xeCD8.InnerText = SalesDTime;

XmlElement xeCD9 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:BeginDateTime", xnsmgr);
xeCD9.InnerText = SalesDTime;

XmlElement xeCD10 = (XmlElement)xDoc.SelectSingleNode("/ns:RetailTransactionLogDirectInsertRequest/ns:POSLog/ix:Transaction/ix:EndDateTime", xnsmgr);
// 原代码里xeCD10重复选了BeginDateTime,这里修正为EndDateTime
xeCD10.InnerText = SalesDTime;

关键修正点

  • 注册双命名空间:为根节点和Transaction节点分别注册命名空间前缀(ns和ix),XPath中对应节点使用正确的前缀
  • 修正XPath路径:从根节点开始完整定位,确保每个节点都匹配对应的命名空间
  • 修复代码错误:删除重复的xeID定义,修正eCD2的拼写错误,调整重复的BeginDateTime选择为EndDateTime

额外优化建议

如果你的.NET版本支持,建议使用XDocument(LINQ to XML)来处理多命名空间XML,代码更简洁易维护:

XDocument xDoc = XDocument.Load(asmbly.GetManifestResourceStream("DaxWebServiceLib.sales.xml"));
XNamespace ns = "http://retalix.com/R10/services";
XNamespace ix = "http://www.nrf-arts.org/IXRetail/namespace/";

xDoc.Descendants(ix + "WorkstationID").First().Value = "0001";
xDoc.Descendants(ix + "POSItemID").First().Value = UPC;
// 其他节点修改以此类推

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:35:54