我有以下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">
<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>
我目前正尝试使用以下c#代码提取但仍无法提取上述数据。我得到一个nullreferenceexception。
XmlDocument doc = new XmlDocument();
doc.Load(folder + "\\" + o.ToString());
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace("cdsd", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode firstName = doc.DocumentElement.SelectSingleNode("/PatientRecord/Demographics/Names/cdsd:LegalName/cdsd:FirstName/cdsd:Part", namespaceManager);
string fName = firstName.InnerText;
MessageBox.Show(fName);
我可以在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>
答案 0 :(得分:0)
PatientRecord
,Demographics
和Names
位于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
。
答案 1 :(得分:0)
文档中有3个名称空间定义:
cds
- 作为默认命名空间http://www.w3.org/2001/XMLSchema-instance
- 使用xsi
前缀cds_dt
- 使用cdsd
前缀我想知道您没有收到错误消息,因为cds
和cds_dt
没有URI,而namspaces需要是URI。
如果您尝试了解元素名称,则需要将前缀替换为实际名称空间。
<PatientRecord>
读为{cds}:PatientRecord
<cdsd:LegalName>
读为{cds_dt}:LegalName
现在在XPath 1.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表达式的第一个字符是斜杠,则表达式相对于文档,否则相对于当前上下文节点。您在SelectSingleNode()
- doc.DocumentElement
元素节点上调用OmdCds
。 PatientRecord
是一个子节点,因此您可以从它开始,或者使用.
作为当前上下文节点。
答案 2 :(得分:-1)
相反,您可以使用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属性beacuse元素具有前缀“cdsd”