如何使用 MSXML 查询默认命名空间 [英] How to query default namespace with MSXML
问题描述
我有一些 XML:
<?xml version="1.0" ?>
<Project ToolsVersion="4.0">
<PropertyGroup Condition="'$(key)'=='1111'">
<Key>Value</Key>
</PropertyGroup>
</Project>
注意:这不是我正在使用的实际 XML,它只是更漂亮和更短,并说明了问题.
Note: This isn't the actual XML i'm using, it's just prettier and shorter, and demonstrates the problem.
使用 MSXML 我可以查询节点:
Using MSXML i can query for nodes:
IXMLDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition");
它工作正常:
条件="'$(key)'=='1111'"
Condition="'$(key)'=='1111'"
但这并不是我真正拥有的 XML
实际上,我拥有的 XML 包含一个命名空间声明:
But that's not really the XML i have
In reality the XML i have contains a namespace declaration:
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
制作实际 XML 文档:
<?xml version="1.0" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(key)'=='1111'">
<Key>Value</Key>
</PropertyGroup>
</Project>
现在我的查询:
IDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition");
没有返回匹配的节点.
如何使用 MSXML 查询默认命名空间?
How do i query the default namespace using MSXML?
注意:
我已经知道如何查询xml 中的非默认命名空间;你使用:
i already know how to query the non-default namespace in xml; you use:
doc.setProperty("SelectionNamespaces",
"xmlns="http://schemas.microsoft.com/developer/msbuild/2003");
我已经知道如何查询 .NET 中的默认命名空间.您使用命名空间管理器,为默认命名空间命名,然后使用该名称进行查询,然后您可以查询非默认命名空间,因为它不再是默认的
i already know how to query the default namespace in .NET. You use the namespace manager, give the default namespace a name, then query using that name, then you can query the non-default namespace since it's no longer default
我可以只是从我收到的 XML 字符串中删除令人反感的 xmlns
文本,但我宁愿以正确的方式去做"
i can just delete the offensive xmlns
text from the XML string i receive, but i'd rather "do it the right way"
如何使用 MSXML 查询 default" 或 unnamed" 命名空间?
How do i query the "default", or "unnamed" namespace using MSXML?
注意:实际上我使用的是 SQL Server 的 XML ShowPlan 输出的 XML:
Note: In reality the XML i am using the SQL Server's XML ShowPlan output:
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<ShowPlanXML Version="1.1" Build="10.50.1600.1"
xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
...
</Batch>
</BatchSequence>
</ShowPlanXML>
您再次可以看到有问题的命名空间声明.删除它有效,但很乏味.
Again you can see the offending namespace declaration. Deleting it works, but that's tedious.
我也尝试设置SelectionNamespace:
doc.setProperty('SelectionNamespaces',
'xmlns="http://schemas.microsoft.com/developer/msbuild/2003"');
实际上我并不关心命名空间.我的查询是有道理的,我希望它起作用.所以,这个问题的另一种方法可能是:
In reality i don't care about namespaces. My query makes sense, and i want it to work. So, Another approach to the question might be:
我如何查询默认命名空间,无论该命名空间名称是否是(或不是)?
How can i query the default namespace whether, or not, and no matter what, that namespace name is (or isn't)?
注意:msxml 是本机代码,从本机 Win32 编译器(即没有 .NET 框架或 CLR)使用它
Note: msxml is native code, and using it from a native Win32 compiler (i.e. no .NET framework or CLR)
推荐答案
在将命名空间添加到 SelectionNamespaces
时,显式地为其命名:
Explicitly give the namespace a name when you add it to the SelectionNamespaces
:
doc.setProperty("SelectionNamespaces",
"xmlns:peanut='http://schemas.microsoft.com/developer/msbuild/2003'");
然后查询使用那个命名空间:
and then query using that namespace:
IDOMNode node = doc.selectSingleNode("//peanut:PropertyGroup/@Condition");
您可以为该命名空间指定任何您想要的缩写名称(在本例中为 peanut
).然后使用缩写作为前缀(在本例中为peanut:PropertyGroup
).
You can give that namespace any abbreviation name you want (peanut
in this case). And then use the abbreviation as prefix (peanut:PropertyGroup
in this case).
我会尝试转向 Xml.Linq
.
这是一个示例(带有命名空间).
Here is a sample (with a namespace).
try
{
XDocument xDoc1 = XDocument.Parse("<?xml version=\"1.0\" ?><Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"><PropertyGroup Condition=\"'$(key)'=='1111'\"><Key>Value</Key></PropertyGroup></Project>");
XNamespace ns1 = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
var list1 = from list in xDoc1.Descendants(ns1 + "Project")
from item in list.Elements(ns1 + "PropertyGroup")
/* where item.Element(ns + "HintPath") != null */
where item.Attribute("Condition") != null
select new
{
MyCondition = item.Attribute("Condition") == null ? "Not Here!" : item.Attribute("Condition").Value,
MyFake = item.Attribute("DoesNotExistTest") == null ? "Not Here Sucker!" : item.Attribute("DoesNotExistTest").Value
};
foreach (var v in list1)
{
Console.WriteLine(v.ToString());
}
XDocument xDoc2 = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?> <ShowPlanXML Version=\"1.1\" Build=\"10.50.1600.1\" xmlns=\"http://schemas.microsoft.com/sqlserver/2004/07/showplan\"> <BatchSequence> <Batch>Something I Threw In Here</Batch> </BatchSequence> </ShowPlanXML> ");
XNamespace ns2 = XNamespace.Get("http://schemas.microsoft.com/sqlserver/2004/07/showplan");
var list2 = from list in xDoc2.Descendants(ns2 + "ShowPlanXML")
from item in list.Elements(ns2 + "BatchSequence")
/* where item.Attribute("Condition") != null */
where item.Element(ns2 + "Batch") != null
select new
{
BatchValue = (item.Element(ns2 + "Batch") == null) ? string.Empty : item.Element(ns2 + "Batch").Value
};
foreach (var v in list2)
{
Console.WriteLine(v.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
这篇关于如何使用 MSXML 查询默认命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!