gpt4 book ai didi

C# 将 XPath 与 XmlDocument 结合使用 - 无法选择命名空间中的节点(返回 null)

转载 作者:行者123 更新时间:2023-12-02 02:33:04 29 4
gpt4 key购买 nike

我正在尝试做一些应该很简单的事情,但我遇到了可怕的麻烦。我已经尝试过 StackOverflow 中多个类似问题的代码,但没有成功。我正在尝试通过澳大利亚政府的 ABN 查询来获取各种信息。以下是匿名返回 XML 值:

    <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ABRSearchByABNResponse xmlns="http://abr.business.gov.au/ABRXMLSearch/">
<ABRPayloadSearchResults>
<request>
<identifierSearchRequest>
<authenticationGUID>00000000-0000-0000-0000-000000000000</authenticationGUID>
<identifierType>ABN</identifierType>
<identifierValue>00 000 000 000</identifierValue>
<history>N</history>
</identifierSearchRequest>
</request>
<response>
<usageStatement>The Registrar of the ABR monitors the quality of the information available on this website and updates the information regularly. However, neither the Registrar of the ABR nor the Commonwealth guarantee that the information available through this service (including search results) is accurate, up to date, complete or accept any liability arising from the use of or reliance upon this site.</usageStatement>
<dateRegisterLastUpdated>2017-01-01</dateRegisterLastUpdated>
<dateTimeRetrieved>2017-01-01T00:00:00.2016832+10:00</dateTimeRetrieved>
<businessEntity>
<recordLastUpdatedDate>2017-01-01</recordLastUpdatedDate>
<ABN>
<identifierValue>00000000000</identifierValue>
<isCurrentIndicator>Y</isCurrentIndicator>
<replacedFrom>0001-01-01</replacedFrom>
</ABN>
<entityStatus>
<entityStatusCode>Active</entityStatusCode>
<effectiveFrom>2017-01-01</effectiveFrom>
<effectiveTo>0001-01-01</effectiveTo>
</entityStatus>
<ASICNumber>000000000</ASICNumber>
<entityType>
<entityTypeCode>PRV</entityTypeCode>
<entityDescription>Australian Private Company</entityDescription>
</entityType>
<goodsAndServicesTax>
<effectiveFrom>2017-01-01</effectiveFrom>
<effectiveTo>0001-01-01</effectiveTo>
</goodsAndServicesTax>
<mainName>
<organisationName>COMPANY LTD</organisationName>
<effectiveFrom>2017-01-01</effectiveFrom>
</mainName>
<mainBusinessPhysicalAddress>
<stateCode>NSW</stateCode>
<postcode>0000</postcode>
<effectiveFrom>2017-01-01</effectiveFrom>
<effectiveTo>0001-01-01</effectiveTo>
</mainBusinessPhysicalAddress>
</businessEntity>
</response>
</ABRPayloadSearchResults>
</ABRSearchByABNResponse>
</soap:Body>
</soap:Envelope>

所以我想使用 xpath="//response" 获得整个响应然后在该节点内使用各种 xpath 语句来获取 <organisationName> ("//mainName/organizationName") 和其他值。应该很简单吧?在 Notepad++ 中测试时,这些 xpath 语句似乎有效,但我在 Visual Studio 中使用此代码:

XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(ipxml);
XmlNode xnode = xdoc.SelectSingleNode("//response");
XmlNodeList xlist = xdoc.SelectNodes("//mainName/organisationName");
xlist = xdoc.GetElementsByTagName("mainName");

但它总是返回 null,无论我在 xpath 中输入什么,无论我是否选择带有子节点的内容(无论是否有值),我都会得到节点的 null 返回值和列表的 0 计数。我可以使用 GetElementsByTagName() 获取节点就像返回正确节点的示例一样,但我想使用 xpath “正确”选择正确的字段。

我也尝试过使用 XElement 和 Linq 但仍然没有成功。 XML 有什么奇怪的地方吗?

我确信这一定很简单,但我已经奋斗了很多年了。

最佳答案

您没有处理文档中存在的命名空间。具体来说,高级元素:

<ABRSearchByABNResponse xmlns="http://abr.business.gov.au/ABRXMLSearch/">

ABRSearchByABNResponse 及其所有子元素(除非被另一个 xmlns 覆盖)放入命名空间 http://abr.business.gov.au/ABRXMLSearch/.为了导航到这些节点(无需使用 GetElementsByTagName 等黑客手段或使用 local-name()),您需要使用 XmlNamespaceManager< 注册命名空间,就像这样。 xmlns 别名不一定需要与原始文档中使用的别名相匹配,但这样做是一个很好的约定:

Xml文档

var xdoc = new XmlDocument();
var ns = new XmlNamespaceManager(xdoc.NameTable);
ns.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("abr", "http://abr.business.gov.au/ABRXMLSearch/");

xdoc.LoadXml(ipxml);
// NB need to use the overload accepting a namespace
var xresponse = xdoc.SelectSingleNode("//abr:response", ns);
var xlist = xdoc.SelectNodes("//abr:mainName/abr:organisationName", ns);

X文档

最近,可以通过 XDocument 来利用 LINQ 的强大功能。 ,这使得命名空间的使用变得更加容易(后代在任何深度查找子节点)

var xdoc = XDocument.Parse(ipxml);
XNamespace soap = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace abr = "http://abr.business.gov.au/ABRXMLSearch/";

var xresponse = xdoc.Descendants(abr + "response");
var xlist = xdoc.Descendants(abr + "organisationName");

XDocument + XPath

您还可以resort to using XPath在 Linq to Xml 中,特别是对于更复杂的表达式:

var xdoc = XDocument.Parse(ipxml);
var ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("abr", "http://abr.business.gov.au/ABRXMLSearch/");

var xresponse = xdoc.XPathSelectElement("//abr:response", ns);
var xlist = xdoc.XPathSelectElement("//abr:mainName/abr:organisationName", ns);

关于C# 将 XPath 与 XmlDocument 结合使用 - 无法选择命名空间中的节点(返回 null),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50492166/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com