2012-01-13 84 views
1

我正在用C#编写一个自定义的WebDAV服务器。我使用的客户端测试程序之一是NetDrive,它声称并且似乎是符合WebDAV的客户端。我的问题是,我在下面的格式。在接收服务器上的请求:如何在C#中处理webdav服务器XML请求#

<?xml version="1.0" encoding="utf-8"?> 
<propfind xmlns="DAV:"> 
    <allprop/> 
</propfind> 

但其他客户做到这一点:

<?xml version="1.0" encoding="utf-8"?> 
<D:propfind xmlns:D="DAV:"> 
    <D:allprop/> 
</D:propfind> 

两个不同的命名空间形式继续fooing我的逻辑去寻找“allprop”元素。我的代码看起来有点像这样:

string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\"><allprop/></propfind>"; //Hardcode to make all the StackOverflow users' lives easier 
XPathDocument doc = new XPathDocument(new StringReader(xml)); 
XPathNavigator nav = doc.CreateNavigator(); 
XPathNodeIterator it = nav.Select("/propfind/*"); 

现在,我知道我需要把某种类型的命名空间管理,为“DAV:”所以我尝试这样做:

XmlNamespaceManager nsman = new XmlNamespaceManager(nav.NameTable); 
nsman.AddNamespace("", "DAV"); 
XPathNodeIterator it = nav.Select("/propfind/*", nsman); 

但我在我的迭代器中没有为第一个XML文件获取节点。看起来默认的命名空间并不像我认为的那样工作。

我在做什么错?当命名空间可能是默认的,或者可能被显式命名时,如何查询此XML是否存在allprop节点?

回答

0

我结束了寻找命名空间URI(DAV :)并添加它,如果它不存在。然后,我只做了一个命名空间合格的SELECT,它在我所有的测试用例中都能正常工作:

XPathDocument document = new XPathDocument(xml); 
XPathNavigator navigator = document.CreateNavigator(); 

//Get namespaces & add them to the search 
bool hasDAV = false; 
string davPrefix = "D"; 
XmlNamespaceManager nsman = new XmlNamespaceManager(navigator.NameTable); 

foreach (KeyValuePair<string, string> nskvp in navigator.GetNamespacesInScope(XmlNamespaceScope.All)) 
{ 
    if (string.Compare(nskvp.Value, "DAV:", StringComparison.InvariantCultureIgnoreCase) == 0) 
    { 
     hasDAV = true; 
     davPrefix = nskvp.Key; 
    } 
    nsman.AddNamespace(nskvp.Key, nskvp.Value); 
} 

if (!hasDAV) 
    nsman.AddNamespace(davPrefix , "DAV:"); 


XPathNodeIterator iterator = navigator.Select("/" + davPrefix + ":" + WebDavXML.PropFind + "/*", nsman); 
1

您的代码中使用了错误的名称空间。 Unforunalely WebDAV规范使用 'DAV:'作为WebDAV节点和属性的名称空间(这似乎是由于对XML名称空间机制的误解造成的)。

相关问题