Как обработать XML-запрос webdav-сервера в C # - PullRequest
1 голос
/ 13 января 2012

Я пишу пользовательский сервер WebDAV на C #.Одна из программ тестирования клиента, которую я использую, - NetDrive , и она претендует и выглядит как клиент, совместимый с WebDAV.Моя проблема в том, что я получаю запрос на сервере в следующем формате:

<?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>

Два разных формата пространства имен продолжают сбрасыватьлогика искать элемент "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, когда пространство имен может быть по умолчанию или может иметь явное имя?

Ответы [ 2 ]

1 голос
/ 13 января 2012

Вы используете неправильное пространство имен в своем коде. Неправильно использовать спецификации WebDAV «DAV:» как пространство имен для узлов и атрибутов WebDAV (похоже, это вызвано неправильное понимание механизма пространства имен XML).

0 голосов
/ 13 января 2012

Я закончил поиском 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);
...