java xml 节点路径,SelectSingleNode使用XPath为已知良好的xml节点路径返回null

回答(9)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

我强烈怀疑问题与名称空间有关 . 尝试摆脱名称空间,你会没事的 - 但显然这对你的实际情况没有帮助,我认为这个文件是固定的 .

我不记得如何在XPath表达式中指定命名空间,但我确信这是问题所在 .

编辑:好的,我've remembered how to do it now. It'虽然不是很令人愉快 - 你需要为它创建一个 XmlNamespaceManager . 以下是一些适用于您的示例文档的示例代码:

using System;

using System.Xml;

public class Test

{

static void Main()

{

XmlDocument doc = new XmlDocument();

XmlNamespaceManager namespaces = new XmlNamespaceManager(doc.NameTable);

namespaces.AddNamespace("ns", "urn:hl7-org:v3");

doc.Load("test.xml");

XmlNode idNode = doc.SelectSingleNode("/My_RootNode/ns:id", namespaces);

string msgID = idNode.Attributes["extension"].Value;

Console.WriteLine(msgID);

}

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

如果要完全忽略名称空间,可以使用:

static void Main(string[] args)

{

string xml =

"\n" +

" \n" +

" \n" +

"";

XmlDocument doc = new XmlDocument();

doc.LoadXml(xml);

XmlNode idNode = doc.SelectSingleNode("/*[local-name()='My_RootNode']/*[local-name()='id']");

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

这应该适用于你的情况而不删除命名空间:

XmlNode idNode = myXmlDoc.GetElementsByTagName("id")[0];

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

对不起,您忘记了命名空间 . 你需要:

XmlNamespaceManager ns = new XmlNamespaceManager(myXmlDoc.NameTable);

ns.AddNamespace("hl7","urn:hl7-org:v3");

XmlNode idNode = myXmlDoc.SelectSingleNode("/My_RootNode/hl7:id", ns);

事实上,无论是在这里还是在Web服务中,从XPath操作或依赖于XPath的任何东西获取null通常都表明XML命名空间存在问题 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

嗯......我遇到了同样的问题而且很头疼 . 由于我不太关心命名空间或xml架构,我只是从我的xml中删除了这些数据,它解决了我所有的问题 . 可能不是最好的答案?可能,但如果您不想处理所有这些并且您只关心数据(并且不会将xml用于其他任务),删除命名空间可能会解决您的问题 .

XmlDocument vinDoc = new XmlDocument();

string vinInfo = "your xml string";

vinDoc.LoadXml(vinInfo);

vinDoc.InnerXml = vinDoc.InnerXml.Replace("xmlns=\"http://tempuri.org\/\", "");

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

只是为了解决命名空间问题,在我的情况下,我一直在运行具有多个命名空间的文档,并且需要正确处理命名空间 . 我编写了下面的函数来获取命名空间管理器来处理文档中的任何命名空间:

private XmlNamespaceManager GetNameSpaceManager(XmlDocument xDoc)

{

XmlNamespaceManager nsm = new XmlNamespaceManager(xDoc.NameTable);

XPathNavigator RootNode = xDoc.CreateNavigator();

RootNode.MoveToFollowing(XPathNodeType.Element);

IDictionary NameSpaces = RootNode.GetNamespacesInScope(XmlNamespaceScope.All);

foreach (KeyValuePair kvp in NameSpaces)

{

nsm.AddNamespace(kvp.Key, kvp.Value);

}

return nsm;

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

只需使用// id而不是/ id . 它在我的代码中工作正常

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

要记住的规则是:如果您的文档指定 namespace ,则必须在调用 SelectNodes() 或 SelectSingleNode() 时使用 XmlNamespaceManager . 这是好事 .

请参阅文章Advantages of namespaces . Jon Skeet在他的答案中做得很好,展示了如何使用 XmlNamespaceManager . (这个答案应该只是对答案的评论,但我没有足够的Rep Points来评论 . )

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

Roisgoen的回答对我有用,但为了使它更通用,你可以使用RegEx:

//Substitute "My_RootNode" for whatever your root node is

string strRegex = @"\s+xmlns([\s]|[^>])*)>";

var myMatch = new Regex(strRegex, RegexOptions.None).Match(myXmlDoc.InnerXml);

if (myMatch.Success)

{

var grp = myMatch.Groups["xmlns"];

if (grp.Success)

{

myXmlDoc.InnerXml = myXmlDoc.InnerXml.Replace(grp.Value, "");

}

}

我完全承认这不是一个最佳实践答案,但它是一个简单的解决方案,有时这就是我们所需要的 .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值