如何正确解析具有任意名称空间的XML文档

时间:2010-10-20 19:08:17

标签: c# xml namespaces

我正在尝试解析一些使用来自各种来源的名为MARCXML的模式的标准XML文档。

以下是需要处理的示例XML文件的前几行......

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
  <marc:record>
    <marc:leader>00925njm  22002777a 4500</marc:leader>

和一个没有名称空间前缀......

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<collection xmlns="http://www.loc.gov/MARC21/slim">
  <record>
    <leader>01142cam  2200301 a 4500</leader>

关键点:为了让XPath在程序中进一步解析,我必须通过正则表达式例程将命名空间添加到NameTable(默认情况下不会添加它们) )。这对我来说似乎没用。

Regex xmlNamespace = new Regex("xmlns:(?<PREFIX>[^=]+)=\"(?<URI>[^\"]+)\"", RegexOptions.Compiled);

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlRecord);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);

MatchCollection namespaces = xmlNamespace.Matches(xmlRecord);
foreach (Match n in namespaces)
{
    nsMgr.AddNamespace(n.Groups["PREFIX"].ToString(), n.Groups["URI"].ToString());
}

XPath调用看起来像这样......

XmlNode leaderNode = xmlDoc.SelectSingleNode(".//" + LeaderNode, nsMgr);

其中LeaderNode是可配置的值,在第一个示例中等于"marc:leader",在第二个示例中等于"leader"

有更好,更有效的方法吗?注意:欢迎使用LINQ解决此问题的建议,但我主要想知道如何使用XmlDocument解决此问题。

编辑:我接受了GrayWizardx的建议,现在有以下代码......

if (LeaderNode.Contains(":"))
{
    string prefix = LeaderNode.Substring(0, LeaderNode.IndexOf(':'));
    XmlNode root = xmlDoc.FirstChild;
    string nameSpace = root.GetNamespaceOfPrefix(prefix);
    nsMgr.AddNamespace(prefix, nameSpace);
}

现在不再依赖Regex!

1 个答案:

答案 0 :(得分:2)

如果知道,文档中将有一个给定元素(例如根元素),您可以尝试使用GetNamespaceOfPrefix