Проблема в том, что элемент sitemapindex
определяет пространство имен по умолчанию. Вам нужно указать пространство имен, когда вы выбираете узлы, иначе они их не найдут. Например:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
Обычно, используя XmlNameSpaceManager
, вы можете оставить префикс пустой строкой, чтобы указать, что это пространство имен является пространством имен по умолчанию. Поэтому вы могли бы подумать, что сможете сделать что-то вроде этого:
// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
Однако, если вы попробуете этот код, вы обнаружите, что он не найдет подходящих узлов. Причина этого заключается в том, что в XPath 1.0 (что и реализуется XmlDocument), когда пространство имен не предоставляется, оно всегда использует пустое пространство имен, а не пространство имен по умолчанию. Таким образом, не имеет значения, укажите ли вы пространство имен по умолчанию в XmlNamespaceManager
, оно не будет использоваться XPath. Чтобы процитировать соответствующий абзац из Официальной спецификации XPath :
QName в тесте узла расширяется в расширенное имя, используя объявления пространства имен из контекста выражения. Точно так же выполняется расширение для имен типов элементов в начальных и конечных тегах, за исключением того, что пространство имен по умолчанию, объявленное с помощью xmlns, не используется: если QName не имеет префикса, тогда URI пространства имен имеет значение NULL (это то же самое имена атрибутов пути). Это ошибка, если в QName есть префикс, для которого нет объявления пространства имен в контексте выражения.
blockquote>Поэтому, когда элементы, которые вы читаете, принадлежат пространству имен, вы не можете избегайте помещать префикс пространства имен в ваши инструкции XPath. Однако, если вы не хотите помещать URI пространства имен в свой код, вы можете просто использовать объект
XmlDocument
для возврата URI корневого элемента, который в этом случае является тем, что вы хотите. Например:XmlDocument xml = new XmlDocument(); xml.Load("sitemap.xml"); XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable); manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);