尽管有XmlNamespaceManager,XPathNavigator仍无法找到节点

时间:2015-02-17 15:47:57

标签: c# .net xml xsd xpathnavigator

我讨厌问另一个XPath / XmlNamespaceManager问题,但我似乎无法解决这个问题。

我使用了XpathVisualizer工具,可以使用XPath“// FuelGradeMovement”正确检测节点。它识别了名称空间,并像那样评估了XPath。

我只想检查节点“ FuelGradeMovement ”是否存在。很容易。但不,不起作用。

显然,我是xpath的节点甚至没有前缀,但如果我不使用命名空间管理器,我会收到运行时错误,因为文档中的其他节点都有前缀。

对于命名空间,由于某种原因,它只是看不到节点。

我正在尝试解析此文档:

    <?xml version="1.0"?>
<NAXML-MovementReport version="3.4" xmlns="http://www.naxml.org/POSBO/Vocabulary/2003-10-16" xmlns:radiant="http://www.radiantsystems.com/NAXML-Extension" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.naxml.org/POSBO/Vocabulary/2003-10-16 NAXML-PBI34RadiantExtended.xsd">
    <TransmissionHeader>....
    </TransmissionHeader>
    <FuelGradeMovement/>
</NAXML-MovementReport>

使用此代码:

    using ( var fs = file.OpenRead() )
{
    var x = new XPathDocument( fs );

    var nav = x.CreateNavigator();
    var mgr = new XmlNamespaceManager( nav.NameTable );

    mgr.AddNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
    mgr.AddNamespace( "xmime", "http://www.w3.org/2005/05/xmlmime" );
    mgr.AddNamespace( "radiant", "http://www.radiantsystems.com/NAXML-Extension" );
    mgr.AddNamespace( "ns1", "http://www.naxml.org/POSBO/Vocabulary/2003-10-16" );

    var iterator = nav.Select( "//FuelGradeMovement", mgr );

    return iterator.Count > 0;
}

我尝试了很多组合,但我没有看到我的错误。 有人可以帮忙吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

您正在指定命名空间管理器 - 但不是命名空间。 FuelGradeMovement元素已从其父级继承了"http://www.naxml.org/POSBO/Vocabulary/2003-10-16"命名空间URI,因此我相信您需要:

var iterator = nav.Select("//ns1:FuelGradeMovement", mgr);

仅仅因为元素没有指定命名空间前缀并不意味着它不在命名空间中。

请注意,除非您真的需要复杂的XPath查询,否则LINQ to XML会使所有这些变得更加简单。例如:

var doc = XDocument.Load(fs);
XNamespace ns = "http://www.naxml.org/POSBO/Vocabulary/2003-10-16";
return doc.Descendants(ns + "FuelGradeMovement").Any();