无法读取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
相关产品推荐
相关产品推荐

