我有一个带有默认命名空间的XML文档.我正在使用XPathNavigator使用Xpath选择一组节点,如下所示:
XmlElement myXML = ...;
XPathNavigator navigator = myXML.CreateNavigator();
XPathNodeIterator result = navigator.Select("/outerelement/innerelement");
Run Code Online (Sandbox Code Playgroud)
我没有得到任何结果:我假设这是因为我没有指定命名空间.如何在我的选择中包含命名空间?
让我们得到一个深度为N的xml树.我已经知道最后一个节点意味着我在最后的注释.现在我想回到最后一个节点的xml树中的某个级别(比如N-3).
请让我知道XPATH查询的语法,以便我可以到达xml树中的预期节点.
这似乎不应该是困难的,但我现在卡住了.我正在尝试从与给定XPath查询字符串匹配的节点获取特定属性的属性值.这是我到目前为止所拥有的:
public static IEnumerable<string> GetAttributes(this XmlDocument xml,
string xpathQuery, string attributeName)
{
var doc = new XPathDocument(new XmlNodeReader(xml));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression expr = nav.Compile(xpathQuery);
XPathNodeIterator iterator = nav.Select(expr);
while (iterator.MoveNext())
{
XPathNavigator curNav = iterator.Current;
if (curNav.HasAttributes)
{
XmlNode curNode = ((IHasXmlNode)curNav).GetNode();
if (null != curNode)
{
XmlAttribute attrib = curNode.Attributes[attributeName];
if (null != attrib)
{
yield return attrib.Value;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这目前抛出异常:
System.InvalidCastException:无法将类型为"MS.Internal.Xml.Cache.XPathDocumentNavigator"的对象强制转换为"System.Xml.IHasXmlNode".
我错了吗?是否有更简单的方法从匹配节点获取属性值?
我正在尝试为XPath创建一个'AET'(抽象表达式树)(因为我正在编写一个WYSIWYG XSL编辑器).在过去的三到四个小时里,我一直用XPath BNF撞墙.
我想到了另一个解决方案.我想我可以编写一个实现IXPathNavigable的类,它在调用CreateNavigator时返回我自己的XPathNavigator.这个XPathNavigator总是会在任何方法调用上成功,并会跟踪这些调用 - 例如我们移动到客户节点,然后移动到客户节点.然后我可以使用这些信息(希望)来创建'AET'(因此我们现在可以在对象模型中拥有客户/客户).
唯一的问题是:如何在地球上我通过XPathExpression运行IXPathNavigable?
我知道这太懒了.但是有没有其他人经历过努力并编写了一个XPath表达式解析器?我还没有POC我可能的解决方案,因为我无法测试它(因为我无法对IXPathNavigable运行XPathExpression),所以我甚至不知道我的解决方案是否能够正常工作.
刚刚开始我的第一次参加XPathNavigator.
这是我的简单xml:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<theroot>
<thisnode>
<thiselement visible="true" dosomething="false"/>
<another closed node />
</thisnode>
</theroot>
Run Code Online (Sandbox Code Playgroud)
现在,我正在使用该CommonLibrary.NET库来帮助我一点:
public static XmlDocument theXML = XmlUtils.LoadXMLFromFile(PathToXMLFile);
const string thexpath = "/theroot/thisnode";
public static void test() {
XPathNavigator xpn = theXML.CreateNavigator();
xpn.Select(thexpath);
string thisstring = xpn.GetAttribute("visible","");
System.Windows.Forms.MessageBox.Show(thisstring);
}
Run Code Online (Sandbox Code Playgroud)
问题是它无法找到属性.我已经查看了MSDN上的文档,但是无法理解正在发生的事情.
我在使用 XPathNavigator 时遇到问题。我有一个文档,其中有一堆“主题”元素,流中没有命名空间。
我正在使用(表达简化到最低限度,首先我认为我的表达是错误的):
XPathDocument xmlDoc = new XPathDocument( stream );
XPathNavigator xml = xmlDoc.CreateNavigator();
XPathNodeIterator iter = xml.Select( "//topic" );
Run Code Online (Sandbox Code Playgroud)
这是行不通的。我可以选择*/*/*或类似的东西并让我的“主题”元素正常。我尝试在在线测试器和其他语言中运行我的表达式,它们起作用了。
问题:怎么了?我一直怀疑它与该死的 NamespaceManager 对象有关,每次我用命名空间解析文档时,这都会给我带来难以置信的痛苦,但这次我正在寻找的元素没有显式命名空间!我补充道:
XmlNamespaceManager s = new XmlNamespaceManager( xml.NameTable );
Run Code Online (Sandbox Code Playgroud)
并将其作为第二个参数传递给 Select - 无济于事。我应该如何将“”命名空间添加到这个东西/正确使用它?
或者,更好的是,有没有办法在 .NET 中使用 XPath,而不像在其他语言中那样使用这种可怕的令人厌恶的类?如果我想要命名空间,我可以将它们写在表达式中......
更新:我找到了一个解决方法 - 从根节点复制/粘贴默认 xmlns,然后使用该命名空间:
thisIsRetarded.AddNamespace( "x", "urn:xmind:xmap:xmlns:content:2.0" );
XPathNodeIterator projectIter = projectTree.Select( "//x:topic", thisIsRetarded );
Run Code Online (Sandbox Code Playgroud)
然而,我不应该知道默认的 URI,也不喜欢用不必要的 x:-s 来污染我的表达式。所以我现在只需要回答问题的第二部分。
给定以下XML标记:
<root xmlns="Demo">
<child name="foo"/>
</root>
Run Code Online (Sandbox Code Playgroud)
并且XPathNavigator位于<child>元素上,
string withNs = navigator.GetAttribute("name", navigator.NamespaceURI);
string withoutNs = navigator.GetAttribute("name", "");
Run Code Online (Sandbox Code Playgroud)
产生奇怪的结果:withNs是空的,withoutNs包含foo.
这是为什么?我原以为它会反过来,因为name属性必须Demo像child元素一样在命名空间中.
MSDN文档没有提到传递的任何神奇含义namespaceURI="",所以我假设你必须传递属性的真实命名空间URI.
我有这个xml文件"target.xml":
<World>
<Nkvavn>
<Rcltwkb>
<Pjwrgsik />
<Nemscmll />
<Fnauarnbvw />
<Egqpcerhjgq />
<Olyhryyxi />
<Vvlhtiee />
<Wlsfhmv />
</Rcltwkb>
<Xudbhnakjb>
<Cwxjtkteuji />
<Fbtcvf />
<Uviaceinhl />
</Xudbhnakjb>
<Kgujcymilwr>
<Nlbvgtwoejo />
<Tvufkvmryybh />
<Xtomstcenmp />
<Mhnngf />
<Fjidqdbafxun />
</Kgujcymilwr>
<Taiyiclo>
<Fiecxoxeste />
<Loqxjq />
<Vfsxfilxofe />
<Hroctladlht />
</Taiyiclo>
</Nkvavn>
<Tfrosh>
<Tuqomkytlp>
<Oyvivlvminhn />
<Qeypvfgul />
<Mbapjl />
</Tuqomkytlp>
<Rvxumtj>
<Gkvigncdvgy />
<Okcddyi />
<Vvmacul />
</Rvxumtj>
<Pdjpgexuyc>
<Yvsdmbckurju />
<Bvkxvg />
<Clmrvjwk />
<Hdafjhydj />
<Asauxtnoe />
<Mwcviwmi /> …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,我使用XPathNavigator迭代节点.它工作正常.
但我想知道如果我使用LINQ to Xml ....
我会得到什么好处(性能,可维护性)?
有了XPath,LINQ到Xml的性能如何?
我正在使用C#.net,VS 2010,我的.xml是中等大小.
如何从xml文档中获取信息?我在c:\ temp\data.xml上有一个xml文档,我正在使用visual studio.
我能想到的最接近的是:
XmlDocument xdoc = new XmlDocument();
xdoc.Load(@"C:\temp\data.xml");
date = xdoc.SelectSingleNode("/forcast_informat…
Run Code Online (Sandbox Code Playgroud)
XML文档如下所示:
<?xml version="1.0"?>
-<xml_api_reply version="1">
-<weather section="0" row="0" mobile_zipped="1" mobile_row="0" tab_id="0" module_id="0">
-<forecast_information>
etc etc...
<current_date_time data="2012-08-09 21:53:00 +0000"/>
etc, etc...
Run Code Online (Sandbox Code Playgroud)
我想做的就是抓住2012-08-09 21:53:00 +0000的日期......有什么建议吗?
xpathnavigator ×10
c# ×8
xpath ×7
xml ×5
.net ×2
.net-4.0 ×1
linq-to-xml ×1
namespaces ×1
select ×1
winforms ×1
xmldocument ×1