我正在尝试做一些应该很简单的事情,但我遇到了可怕的麻烦。我在 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>
Run Code Online (Sandbox Code Playgroud)
所以我想获得例如整个响应,xpath="//response"
然后使用该节点内的各种 xpath 语句来获取<organisationName>
("//mainName/organisationName") 和其他值。应该很简单吧?在 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");
Run Code Online (Sandbox Code Playgroud)
但它总是返回空值,无论我在 xpath 中放什么,我都会得到节点的空值返回值和列表的 0 计数值,无论我选择的是带有子节点的东西,还是值。我可以使用GetElementsByTagName()
返回正确节点的示例来获取节点,但我想通过使用 xpath 来“正确”选择正确的字段。
我也尝试过使用 XElement 和 Linq,但仍然没有运气。XML 有什么奇怪的地方吗?
我敢肯定它一定很简单,但我一直在努力奋斗。
您不是在处理文档中存在的命名空间。具体来说,高级元素:
<ABRSearchByABNResponse xmlns="http://abr.business.gov.au/ABRXMLSearch/">
Run Code Online (Sandbox Code Playgroud)
将ABRSearchByABNResponse
及其所有子元素(除非被另一个元素覆盖xmlns
)放入命名空间http://abr.business.gov.au/ABRXMLSearch/
。为了导航到这些节点(没有像GetElementsByTagName
或使用这样的黑客local-name()
),您需要使用 注册命名空间XmlNamespaceManager
,就像这样。xmlns
别名不一定需要与原始文档中使用的别名相匹配,但这样做是一个很好的约定:
文档
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);
Run Code Online (Sandbox Code Playgroud)
X文档
最近,可以通过XDocument来利用 LINQ 的强大功能,这使得使用命名空间变得更加容易(Descendants
查找任何深度的子节点)
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");
Run Code Online (Sandbox Code Playgroud)
XDocument + XPath
您还可以在 Linq to Xml 中使用 XPath,尤其是对于更复杂的表达式:
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);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2390 次 |
最近记录: |