2010-10-20 49 views
7

我想解析一些标准的XML文档,它们使用来自各种来源的名为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); 
} 

现在有正则表达式上没有更多的依赖!

+0

我面临几乎完全相同的问题。你如何完成你的'LeaderNode'魔法?你有预知你正在处理什么记录类型? – 2014-02-05 16:28:48

回答

2

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

+0

这看起来很有希望。我会试一试:) – 2010-10-20 22:50:07

+0

我了解命名空间的方式,它们可以在文档中的任何位置声明。你能否抽象出这个方法来处理这个一般情况? – 2014-02-05 16:31:52

+0

@Patrick M我不确定是否诚实。我的理解是,他们必须在文档的根元素上定义,但可能会添加到任何父元素。我没有看过这一段时间。 – GrayWizardx 2014-02-06 18:41:15

相关问题