我有一些XML:
<?xml version="1.0" ?>
<Project ToolsVersion="4.0">
<PropertyGroup Condition="'$(key)'=='1111'">
<Key>Value</Key>
</PropertyGroup>
</Project>
注意:这不是我实际使用的XML,它只是更漂亮,更短,并说明了问题。
使用MSXML我可以查询节点:
IXMLDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition");
它运行良好:
条件= " $(关键)的= = 1111"
但这不是真正的XML,我有
实际上,我拥有的XML包含一个名称空间声明:
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查询默认命名空间?
注意:
我已经知道如何查询非默认命名空间在xml;你使用:
doc.setProperty("SelectionNamespaces", "xmlns="http://schemas.microsoft.com/developer/msbuild/2003");
我已经知道如何查询。net中的默认命名空间。你使用命名空间管理器,给默认命名空间一个名字,然后用这个名字查询,然后你可以查询非默认命名空间因为它不再是默认的
i 可以从我收到的XML字符串中删除冒犯的
xmlns
文本,但我宁愿"以正确的方式做"
如何使用MSXML查询"default"或"unnamed"命名空间?
注意:实际上我使用的是SQL Server的XML ShowPlan输出:
<?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>
您可以再次看到违规的名称空间声明。删除它是可行的,但这很繁琐。
你还试过什么?
我也尝试设置选择命名空间:
doc.setProperty('SelectionNamespaces',
'xmlns="http://schemas.microsoft.com/developer/msbuild/2003"');
正如微软在一篇知识库文章中所暗示的那样。
i 如何获得默认命名空间?
实际上,我不关心名称空间。我的问题是有意义的,我希望它工作。因此,这个问题的另一种方法可能是:
如何查询默认的命名空间是否,以及该命名空间的名称是(或不是)?
注意: msxml是原生代码,并且在本地Win32编译器(即没有。net框架或CLR)中使用
在将名称空间添加到SelectionNamespaces
时显式地为其提供缩写别名:
doc.setProperty("SelectionNamespaces",
"xmlns:peanut='http://schemas.microsoft.com/developer/msbuild/2003'");
,然后使用该名称空间查询(但通过其缩写别名引用):
IDOMNode node = doc.selectSingleNode("//peanut:PropertyGroup/@Condition");
您可以为该名称空间提供任何您想要的缩写别名(这里我使用peanut
的值来演示它可以是您想要的缩写别名的值)。
然后在"搜索条件"中使用相同的缩写别名作为前缀(在本例中为peanut:PropertyGroup
)。
Xml.Linq
。
下面是一个示例(带有名称空间)。
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);
}
标题>如果您像我一样,并且不想更改您的.SelectNodes("//Test")
代码以匹配每个可能的名称空间,您可以参考我的回答如何忽略XML名称空间
.transformNodeToObject
方法:
Public Sub fixNS(ByRef doc As DOMDocument60)
' Create a new XML document (fixNS0) that contains an XSLT style sheet.
' The XSLT style sheet will remove namespace prefixes from XML elements and attributes.
' The resulting XML document will have the same content as the original, but with the namespace prefixes removed.
Dim fixNS0 As New DOMDocument60
fixNS0.LoadXML ("<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" & _
"<xsl:output method='xml' indent='yes' omit-xml-declaration='yes' />" & _
"<xsl:template match='comment()'> <xsl:copy/> </xsl:template>" & _
"<xsl:template match='*'>" & _
"<xsl:text>
</xsl:text>" & _
"<xsl:element name='{local-name(.)}'> <xsl:apply-templates select='@* | node()'/> </xsl:element>" & _
"<xsl:text>
</xsl:text>" & _
"</xsl:template> <xsl:template match='@*'>" & _
"<xsl:attribute name='{local-name(.)}'> <xsl:value-of select='.'/> </xsl:attribute>" & _
"</xsl:template> </xsl:stylesheet>")
' Apply the XSLT style sheet (in fixNS0) to the XML document (in doc).
' The result of the transformation is written back to the same XML document (in doc).
doc.transformNodeToObject fixNS0, doc
End Sub