XPATHS и пространства имен по умолчанию

Какова история XPath и поддержки пространств имен? XPath как спецификация предшествовал пространствам имен? Если у меня есть документ, в котором элементам задано пространство имен по умолчанию:

<foo xmlns="uri" />

Похоже, что некоторые библиотеки процессора XPath не распознают //foo из-за пространства имен, тогда как другие будут. Моя команда подумала о том, чтобы добавить префикс пространства имен с помощью регулярных выражений в XPath (вы можете добавить префикс пространства имен через XmlNameTable), но это кажется хрупким, поскольку XPath является таким гибким языком, когда дело доходит до тестов узлов.

Есть ли стандарт, который применим к этому?

Мой подход немного хакерский, но, кажется, работает нормально; Я удаляю объявление xmlns с поиском / заменой, а затем применяю XPath.

string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty );

Это справедливый подход, или кто-то решил это по-другому?

16
задан 15.12.2019, 12:04

4 ответа

Я попробовал что-то подобное тому, какой предложенный palehorse и не мог заставить его работать. Так как я получал данные из опубликованного сервиса, я не мог изменить xml. Я закончил тем, что использовал XmlDocument и XmlNamespaceManager как так:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlWithBogusNamespace);            
XmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable);
nSpace.AddNamespace("myNs", "http://theirUri");

XmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace);
//etc
10
ответ дан 15.12.2019, 12:06
  • 1
    Если Вы хотите выбрать узлы использования на нескольких глубинах, Вы заканчиваете тем, что имели необходимость сделать что-то как: xml.SelectNodes("kml:kml/kml:Document/kml:Folder", manager) – Drew Noakes 15.12.2019, 12:07

Проблема - то, что элемент без пространства имен, как объявляют, находится в ПУСТОМ пространстве имен - поэтому, если бы//нечто соответствовало против пространства имен, Вы считаете 'значением по умолчанию' не было бы никакого способа относиться к элементу в пустом пространстве имен.

Помнят также, что префикс для пространства имен является только соглашением стенографии, реальное имя элемента (Полностью определенное имя или QName, если коротко) состоит из полного пространства имен и локального имени. Изменение префикса для пространства имен не изменяет 'идентификационные данные' элемента - если это находится в том же пространстве имен и том же локальном имени тогда, это - тот же вид элемента, даже если префикс отличается.

XPath 2.0 (или скорее XSLT 2.0) имеет понятие 'значения по умолчанию xpath пространство имен'. Можно установить атрибут xpath-пространства-имен-по-умолчанию на xsl:stylesheet элементе.

4
ответ дан 15.12.2019, 12:06
  • 1
    Я didn' t тест, но doesn' t второй сбой сдвига, когда существует нечетное число элементов в @list? Но what' s нечетный undef среди друзей.;-) – Jon Ericson♦ 14.03.2020, 07:12

При попытке использовать xslt, можно включить пространство имен к объявлению таблицы стилей. Если Вы делаете это, необходимо удостовериться, что существует префикс, или он не будет работать. Если источник, XML не имеет префикса, который прекрасен все еще, Вы добавляете свой собственный префикс в таблице стилей.

Таблица стилей

<xsl:stylesheet
    xmlns:fb="uri"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="fb:foo/bar">
        <!--  do stuff here -->
    </xsl:template>
</xsl:stylsheet>

Или что-то как этот.

0
ответ дан 15.12.2019, 12:07
  • 1
    @cmartin, ничто в его запросе не предполагает что это can' t израсходовали список. Так, разрушительные списком действия могли бы отвечать всем требованиям. Но, если that' s случай, there' s никакая причина для shift-shift, просто соедините. – Axeman 14.03.2020, 07:13

Вам нужно локальное имя ():

http://www.w3.org/TR/xpath#function-local-name

Для закрепления от http://jcooney.net/archive/2005/08/09/6517.aspx :

<foo xmlns='urn:foo'>
  <bar>
    <asdf/>
  </bar>            
</foo>

Это выражение будет соответствовать элементу “bar”:

  //*[local-name()='bar'] 

Этот не будет:

 //bar
15
ответ дан 15.12.2019, 12:07

Теги

Похожие вопросы