【发布时间】:2010-10-05 07:54:00
【问题描述】:
具体来说(深吸一口气):您将如何在实例的XmlSchemaSet(Schemas 属性)中查找 C#/.NET XmlDocument 中没有适用架构的所有 XML 名称空间?
我的 XPath 魔法缺乏做这种事情的复杂性,但我会在此期间继续寻找......
【问题讨论】:
标签: c# .net xsd schema xml-namespaces
具体来说(深吸一口气):您将如何在实例的XmlSchemaSet(Schemas 属性)中查找 C#/.NET XmlDocument 中没有适用架构的所有 XML 名称空间?
我的 XPath 魔法缺乏做这种事情的复杂性,但我会在此期间继续寻找......
【问题讨论】:
标签: c# .net xsd schema xml-namespaces
我发现从给定 XmlDocument 中检索所有命名空间的最简单方法是通过 XPath 找到唯一的 Prefix 和 NamespaceURI 值的所有节点。
我有一个辅助例程,用于在 XmlNamespaceManager 中返回这些唯一值,以便在处理复杂的 Xml 文档时更轻松。
代码如下:
private static XmlNamespaceManager PrepopulateNamespaces( XmlDocument document )
{
XmlNamespaceManager result = new XmlNamespaceManager( document.NameTable );
var namespaces = ( from XmlNode n in document.SelectNodes( "//*|@*" )
where n.NamespaceURI != string.Empty
select new
{
Prefix = n.Prefix,
Namespace = n.NamespaceURI
} ).Distinct();
foreach ( var item in namespaces )
result.AddNamespace( item.Prefix, item.Namespace );
return result;
}
【讨论】:
您需要获取文档中所有不同命名空间的列表,然后将其与架构集中的不同命名空间进行比较。
但命名空间声明名称通常不会在 XPath 文档模型中公开。但是给定一个节点,您可以获得它的命名空间:
// Match every element and attribute in the document
var allNodes = xmlDoc.SelectNodes("//(*|@*)");
var found = new Dictionary<String, bool>(); // Want a Set<string> really
foreach (XmlNode n in allNodes) {
found[n.NamespaceURI] = true;
}
var allNamespaces = found.Keys.OrderBy(s => s);
【讨论】:
这里是 Marks c# 到 vb.net 的快速转换(对于那些遗留程序):
Friend Function SetupNameSpacesFromFile(ByVal xmlDoc As XmlDocument) As XmlNamespaceManager
Dim result As XmlNamespaceManager = New XmlNamespaceManager(xmlDoc.NameTable)
Dim n As XmlNode
Dim d As Dictionary(Of String, String) = New Dictionary(Of String, String)
For Each n In xmlDoc.SelectNodes("//*|@*")
If n.NamespaceURI <> String.Empty Then
If Not d.ContainsKey(n.Prefix) Then
d.Add(n.Prefix, n.NamespaceURI)
End If
End If
Next
For Each item As KeyValuePair(Of String, String) In d
result.AddNamespace(item.Key, item.Value)
Next
Return result
End Function
【讨论】: