C# 提取父元素位于默认命名空间中的XML子元素
我有下面的XML,一段时间以来我一直在尝试提取FirstName、LastName和OtherName,现在我遇到了各种各样的问题C# 提取父元素位于默认命名空间中的XML子元素,c#,xml,xml-namespaces,C#,Xml,Xml Namespaces,我有下面的XML,一段时间以来我一直在尝试提取FirstName、LastName和OtherName,现在我遇到了各种各样的问题 <OmdCds xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cdsd="cds_dt" xsi:schemaLocation="cds ontariomd_cds.xsd"> <Patien
<OmdCds xmlns="cds"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cdsd="cds_dt"
xsi:schemaLocation="cds ontariomd_cds.xsd">
<PatientRecord>
<Demographics>
<Names>
<cdsd:LegalName namePurpose="L">
<cdsd:FirstName>
<cdsd:Part>SARAH</cdsd:Part>
<cdsd:PartType>GIV</cdsd:PartType>
<cdsd:PartQualifier>BR</cdsd:PartQualifier>
</cdsd:FirstName>
<cdsd:LastName>
<cdsd:Part>GOMEZ</cdsd:Part>
<cdsd:PartType>FAMC</cdsd:PartType>
<cdsd:PartQualifier>BR</cdsd:PartQualifier>
</cdsd:LastName>
<cdsd:OtherName>
<cdsd:Part>GABRIELA</cdsd:Part>
<cdsd:PartType>GIV</cdsd:PartType>
<cdsd:PartQualifier>BR</PartQualifier>
我可以在doc.DocumentElement下的本地监视项中看到所有InnerXML和InnerText。InnerXML看起来像这样
<PatientRecord xmlns=\"cds\"><Demographics><Names><cdsd:LegalName namePurpose=\"L\" xmlns:cdsd=\"cds_dt\"><cdsd:FirstName><cdsd:Part>SARAH</cdsd:Part><cdsd:PartType>GIV</cdsd:PartType><cdsd:PartQualifier>BR</cdsd:PartQualifier></cdsd:FirstName>
PatientRecord、人口统计和姓名位于cds命名空间中。这是因为OmdCds元素xmlns=cds上的默认名称空间声明。其他的在cdsd名称空间中,而不是xsi。您必须添加它们并在XPATH中使用它们:
namespaceManager.AddNamespace("cdsd", "cdsd");
namespaceManager.AddNamespace("cds", "cds");
XmlNode firstName = doc.DocumentElement.SelectSingleNode(
"/cds:PatientRecord/cds:Demographics/cds:Names/cdsd:LegalName/cdsd:FirstName/cdsd:Part",
namespaceManager);
顺便说一句,您得到了一个NullReferenceException,因为您错误地假设查询将始终返回一个节点。现在您可以看到当它不返回节点时会发生什么。只要查询可能不返回值,就始终检查null。可以使用Linq to XML代替XmlDocument类,这很简单。您需要使用System.Xml.Linq namspace,例如:
XDocument xdoc = XDocument.Load("path");
IEnumerable<XElement> nodes = (from p in xdoc.Descendants()
where p.Name.LocalName == "FirstName"
select p).Elements();
foreach (XElement nodeFirstName in nodes)
{
foreach (XElement parts in nodeFirstName.Elements())
{
string strExtracted = parts.Name.LocalName + " " + parts.Value;
}
}
使用LocalName属性是因为元素具有前缀cdsd文档中有3个命名空间定义: cds-作为默认名称空间 http://www.w3.org/2001/XMLSchema-instance- 使用xsi前缀 cds_dt-带有cdsd前缀 我想知道您没有收到错误消息,因为CD和CD_dt不是URI,而NamSpace需要是URI 如果试图理解元素名称,则需要用实际名称空间替换前缀 读作{cds}:PatientRecord 读作{cds_dt}:LegalName 现在在XPath1.0中,注册的名称空间也会发生同样的情况。但是XPath没有默认名称空间。因此,没有名称空间的元素不会用默认名称空间展开 您需要在命名空间管理器上注册命名空间前缀。前缀不需要与文档中的前缀相同
namespaceManager.AddNamespace("cdsd", "cds_dt");
namespaceManager.AddNamespace("cds", "cds");
现在,您可以在XPath中使用已注册的名称空间:
doc.DocumentElement.SelectSingleNode(
"cds:PatientRecord/cds:Demographics/cds:Names/cdsd:LegalName/cdsd:FirstName/cdsd:Part",
namespaceManager
);
如果XPath表达式的第一个字符是斜杠,则该表达式与文档相关,否则与当前上下文节点相关。您可以在doc.document元素上调用SelectSingleNode—OmdCds元素节点。PatientRecord是一个子节点,因此您可以从它开始或使用它。对于当前上下文节点。是否必须使用XmlDocument?使用LINQtoXML通常会使处理名称空间变得更简单。此外,如果您将来能够更加注意愉快地格式化代码和示例XML,这将使您更容易获得帮助?XmlNode firstName=doc.DocumentElement.SelectSingleNode/PatientRecord/Demographics/Names/LegalName/firstName/Part;这里的许多答案缺少xPath的一个关键字符。xPath的开头是这样的。/cds:PatientRecord/-The错过了让我发疯的那段时间,直到我读了一些书并意识到那段时间。缺少。你应该学会使用名称空间,而不是使用本地名称。John,你知道我不知道如何使用它吗?。我正在对这个问题作出迅速而可行的回应。请注意,他是阿坦西翁。这是一个很好的例子。我是萨博·科莫·乌萨罗斯(sabe cómo usarlos),他是一个负责人。顺便说一句,我是对StackOverflow的新评论,我对这个论坛的看法是,它应该帮助人们解决任何问题并提供解决方案,但不要假装是宇宙的主宰。这就是我亲爱的朋友。我在这个网站上的时间比你长一点。顺便说一句,它不是一个论坛,只是需要在XPath的开头加上句点。例如:./cds:PatientRecord/cds…..实际上,您只需删除/。我更新了答案并添加了解释。
doc.DocumentElement.SelectSingleNode(
"cds:PatientRecord/cds:Demographics/cds:Names/cdsd:LegalName/cdsd:FirstName/cdsd:Part",
namespaceManager
);