HTML, XML, пространства имен, XML - PullRequest
2 голосов
/ 19 апреля 2011

Я только что обнаружил некоторые проблемы при разборе html-документов с помощью nekohtml + dom4j.

Я обнаружил, что мои выражения xpath больше не работают из-за нового пространства имен html xml по умолчанию, которое недавно было добавлено в источник HTML.

В спецификации сказано:

Префикс xmlns используется только для объявить привязки пространства имен и является определение привязано к имени пространства имен http://www.w3.org/2000/xmlns/. ДОЛЖЕН НЕ быть объявленным. Другие префиксы ДОЛЖНЫ НЕ привязываться к этому имени пространства имен, и он НЕ ДОЛЖЕН быть объявлен как пространство имен по умолчанию. Имена элементов ДОЛЖНЫ НЕ имеет префикс xmlns.

Но в моих html-документах недавно был добавлен (я полагаю) тег html: xmlns = "http://www.w3.org/1999/xhtml"

Я нашел 2 решения:

1) Удалить пространство имен с помощью:

DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/namespaces", false);
parser.parse(url);

Согласно тому, что сказал NekoHTML faq.

2) Добавить префикс к моему xpath, привязанный к пространству имен html по умолчанию. (Кажется, он не может привязать префикс «пустая строка» к желаемому пространству имен)

Map<String,String> XPATH_NAMESPACES = new HashMap<String, String>();
XPATH_NAMESPACES.put("my_prefix", "http://www.w3.org/1999/xhtml");

XPath xpath = document.createXPath(xpathExpr);
xpath.setNamespaceURIs(XPATH_NAMESPACES);
Element element = (Element) xpath.selectSingleNode(document);

И затем, вместо использования // td для примера, я использую // my_prefix: td

Я просто публикую эти решения, потому что некоторые люди могут найти это сообщение полезным. Смотри также http://www.edankert.com/defaultnamespaces.html#Jaxen_and_Dom4J

Но то, что я действительно хотел бы знать, это:

  • Зачем использовать другое пространство имен из по умолчанию?
  • Зачем кому-то переключаться с http://www.w3.org/2000/xmlns/ на http://www.w3.org/1999/xhtml?
  • Почему мы вообще используем пространства имен w3? Есть ли в пространстве имен влияние на браузер?

Полагаю, мой вопрос может показаться очевидным для некоторых из вас, но я не совсем понимаю, что он приносит. Я читал о различиях между HTML и HTML. Я полагаю, что люди, использующие xhtml dtd, предпочли бы использовать это пространство имен, но в чем реальный интерес, кроме того факта, что он дает дополнительную боль сканерам или другим подобным вещам?

PS: я видел, что для перехода от html к xhtml необходимо добавить xmlns и xml: lang, например: Так что, вероятно, целью веб-сайта, который я анализировал, была не цель, поскольку не было добавлено xml: lang ...

Спасибо

Ответы [ 2 ]

10 голосов
/ 19 апреля 2011

В вашем вопросе довольно много путаницы, и ее нелегко разрешить, не написав полное руководство по пространствам имен XML.Я постараюсь рассказать как можно лучше о том, как они соотносятся с (X) HTML.

Во-первых, целью пространств имен является разделение словарей.Так, например, элемент title в пространстве имен http://www.w3.org/1999/xhtml можно отличить от элемента title в пространстве имен http://www.w3.org/2000/svg, когда они появляются в одном документе или обрабатываются общим процессором.

Во-вторых, забудьте о пространстве имен http://www.w3.org/2000/xmlns/.То, что он делает, в значительной степени скрыто, и вам редко приходится об этом беспокоиться.

Далее необходимо различать пустое пространство имен, пространство имен по умолчанию и пространства имен, на которые ссылаются префиксы.

Когда в XML-файле не определены атрибуты xmlns=, все нефиксированные элементы называются «в нулевом пространстве имен» или «в отсутствие пространства имен», что равносильно одной вещи.

Когда элемент XMLимеет атрибут xmlns=, он и его дочерние элементы, если они не имеют префикса, называются «в пространстве имен по умолчанию», где пространством имен по умолчанию является значение атрибута xmlns.

Префиксные элементы всегда находятся впространство имен, отображаемое с помощью xmlns:prefix= атрибутов в элементе или предке элемента.

Теперь словарь XHTML определен как элементы в пространстве имен http://www.w3.org/1999/xhtml, поэтому в правильно написанном документе XHTML будет объявлено либо это пространство именкак пространство имен по умолчанию или преобразует префикс в пространство имен, в этом случае весь XHTЭлементы ML должны будут включать этот префикс в свои имена.(Последняя ситуация случается не очень часто по причинам, указанным ниже).

Таким образом, при синтаксическом анализе XHTML с помощью синтаксического анализатора XML требуется сопоставление пространства имен.

Однако XPathне имеет понятия пространства имен по умолчанию.Если вы не добавите префикс к элементам, указанным в xpath, он попытается сопоставить элементы в пустом пространстве имен.Если элементы XHTML находятся в пространстве имен http://www.w3.org/1999/xhtml, то xpath не будет ничего совпадать.


Здесь все становится сложнее - браузеры.

Если вы обслуживаетеВеб-страницы XHTML для браузеров, как вам следует, с типом содержимого XML, таким как application / xhtml + xml, браузер будет использовать для его загрузки анализатор XML, и все вышеперечисленные правила применяются.Если вы не включите атрибут xmlns="http://www.w3.org/1999/xhtml", браузеры не поймут, как его обрабатывать, и просто отобразят файл в виде необработанной XML-структуры.

Однако, поскольку IE до IE9 не поддерживал XMLТипы контента, вряд ли кто-то обслуживает свои веб-страницы таким образом.Вместо этого они используют тип содержимого "text / html", и в этом случае браузер вообще не использует синтаксический анализатор XML, он использует HTML.

Анализатор HTML просто игнорирует пространство имен для префикса сопоставлений,и просто «знает», какие имена элементов принадлежат каким пространствам имен.Это делает его в конечном итоге менее гибким, но в пределах его специализированной области, более надежным и простым в использовании.(В приведенном выше примере элемента title он определяет, какое пространство имен применяется, просматривая элементы-предки title s). Именно поэтому в документах XHTML не используются элементы с префиксом, поскольку анализатор HTML не распознает их.

Браузеры, (в любом случае, современные), затем имеют специализированные DOM-подобные API-методы и правила CSS, чтобы скрыть всю эту сложность пространства имен от автора javascript и css, и, таким образом, по большей части пространство имен можетАвторы веб-сайтов должны игнорировать их.

Автономные анализаторы HTML, однако, не всегда делают это.Вместо этого они помещают все элементы в пустое пространство имен, что означает, что их можно найти с помощью xpath, которые не включают префиксы в именах элементов, используя стандартные API-интерфейсы DOM.Для большинства практических целей это то же самое, что и при анализе в браузере с использованием их HTML-анализатора.

Итак, в общем, вам нужно знать, анализируете ли вы свой XHTML с помощью синтаксического анализатора XML или HTML, и как этот конкретный анализатор назначает элементы пространствам имен, чтобы иметь возможность написать правильный xpath для запросадля элементов в документе.

1 голос
/ 19 апреля 2011

Вы неправильно понимаете, что читаете. Пространство имен самого атрибута xmlns должно быть http://www.w3.org/2000/xmlns/. Пространство имен по умолчанию (пространство имен, указанное с помощью xmlns="something", или, конечно, может быть изменено.

Обратите внимание, что

<element1 xmlns="something">
    <element2/>
</element1>

совпадает с

<x:element1 xmlns:x="something">
    <x:element2/>
</x:element1>

Другими словами, пространство имен по умолчанию - это просто удобное сокращение, которое позволяет не указывать префикс для элементов в пространстве имен по умолчанию.

...