Принудительно использовать HTML Tidy для вывода XML (вместо XHTML) или XSLTproc для анализа файлов XHTML. - PullRequest
3 голосов
/ 04 сентября 2011

У меня есть большое количество HTML-файлов, которые мне нужно обработать с помощью XSLT, используя XML-файл, чтобы выбрать, какие HTML-файлы и что мы с ними делаем.

Я пытался:

  1. Используйте HTML Tidy для конвертации HTML -> XHTML / XML
  2. Использовать документ (имя файла) в XSLT для чтения, в частности, файлов XHTML / XML
  3. ... используйте стандартные команды для набора узлов, например, для доступа. "HTML / тело / *"

Это не работает, потому что:

  1. Кажется, что XSLT (пробовал: libXSLT / xsltproc ... и Saxon) не может обрабатывать документы XHTML как внешние файлы (он видит xhtml DOCTYPE и отказывается анализировать его как узлы).

Отлично (подумал я) ... XHTML - это просто XML, мне просто нужно поместить его в HTML Tidy и сказать:

"output-xml yes ... output-html no ... output-xhtml no"

... но HTML Tidy игнорирует вас, если вы попытаетесь это сделать, и вместо этого вынуждает использовать html :(. Кажется, он жестко закодирован для вывода только файлов XML, если для начала ввод был XML.

Любые идеи о том, как:

  1. Заставить HTML Tidy подчиняться параметрам командной строки и установить запрашиваемый тип документа
  2. Принудительно XSLTproc для анализа xhtml DOCTYPE как xml
  3. ... какой-нибудь другой хитрый способ, который будет работать?

Примечание: это должно работать на OS X - это часть процесса сборки приложений iOS. Это не должно быть большой проблемой, но, например, никакие инструменты только для окон недоступны. Я хотел бы добиться этого с помощью стандартных кроссплатформенных инструментов с открытым исходным кодом (таких как tidy, libxslt и т. Д.)

Ответы [ 5 ]

2 голосов
/ 04 сентября 2011

Я наконец-то обнаружил, почему XSLTproc / Saxon отказывались анализировать файлы, если они были переданы с html DOCTYPE:

DOCTYPE внешнего документа изменяет способ интерпретации xmlns (пространства имен) директива.Тиди (правильно) объявлял «xmlns = ... xhtml: namespace» - так что все мои имена узлов были ... Я не знаю: не существует?... внутри моего XSLT.XSLT просто игнорировал их, как если бы они не существовали - мне нужно было предоставить совместимое отображение для одного и того же пространства имен

... странно, если DOCTYPE был xml, то они, к счастью, проигнорироваликоманда xmlns - или они позволили мне ссылаться на узлы по неполному имени.Это обмануло меня, когда я подумал, что они просто игнорируют наборы узлов в версии xhtml DOCTYPE.

Итак, «решение» выглядит примерно так:

  1. изменить вашТаблица стилей XSLT ТАКЖЕ импортирует пространство имен «xhtml» - NB: это необходимо для того, чтобы вы могли ссылаться на узлы во внешних файлах
  2. записать все свои правила совпадения / выбора / шаблона XSL с префиксом «xhtml» вкаждый узел (и каждый атрибут, я думаю?)
  3. позволяет Tidy выводить все, что ему нужно: это не имеет значения, это будет просто работать, как только у вас будет поддержка пространства имен

Пример кода:

  1. Ваша таблица стилей идет от этого:

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

    ... до этого:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
    
  2. Ваш выбор / совпадение / импорт документов происходит от:

    <xsl:copy-of select="document('html-files/file1.htm')/html/body"/>
    

    ... до этого:

    <xsl:copy-of select="document('html-files/file1.htm')/xhtml:html/xhtml:body"/>
    

Примечание: только длябудьте ясны: если вы игнорируете пространства имен, то кажется, что XSLT будет работать для файлов, которые НЕ УДАЛЕНЫ, даже еслипространство имен в них.Не делайте ошибку, которую я сделал, думая, что ваш XSLT верен только потому, что он выглядит так:)

0 голосов
/ 04 сентября 2011

Я думаю, что основная проблема заключается в объявлении типа документа в каталоге XML. Вы можете проверить это, удалив ссылку на внешнюю сущность во входном XHTML и посмотреть, правильно ли с ним работает процессор.

Я бы сделал следующее:

  • Используйте Tidy с опцией doctype .
  • Добавьте Doctype на стороне XSLT, как описано здесь

Основная проблема заключается в том, что Saxon и xsltproc не имеют никакой возможности отключить разрешение внешних объектов. Это поддерживается утилитой командной строки MSXSL.exe с параметром -xe .

0 голосов
/ 04 сентября 2011

Если вы запускаете xsltproc --help, среди принятых входных флагов есть очень заметный флаг под названием --html, который предположительно говорит xsltproc, что:

- html: входной документ (are) HTML-файл (ы)

Предположительно, чтобы это работало, у вас должны быть действительные HTML-файлы для начала.Так что вы можете сначала привести их в порядок.

0 голосов
/ 04 сентября 2011

Прошло много времени, но я помню, как пытался использовать HTMLTidy для подготовки HTML-файлов для XSLT, и был разочарован тем, насколько легко он отказался от попыток «правильно сформировать» HTML.Затем я нашел TagSoup и был очень доволен.

TagSoup также включает в себя процессор командной строки, который читает файлы HTML и может генерировать либо чистый HTML, либо правильно сформированный XML, близкий к XHTML.

Я не знаю, привязаны ли вы к HTMLTidy, но если нет, попробуйте следующее: http://home.ccil.org/~cowan/tagsoup/

Например, вот плохой файл HTML:

<body>
  <p>Testing
</body>

А вот команда tagsoup и ее вывод:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html bad.html 
src: bad.html
<html><body>
  <p>Testing
</p></body></html>

Edit 01

Вот как tagoup обрабатывает DOCTYPEs.

Вот плохой HTML-файл с действительным DOCTYPE:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
  <p>Testing
</body>
</html>

Вот как с ним работает tagoup:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html bad.html 
src: bad.html
<html><body>
  <p>Testing
</p></body></html>

Пока вы явно не передадите DOCTYPE в tagoup, он попытаетсядля вывода одного:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html --doctype-public=html bad.html 
src: bad.html
<!DOCTYPE  PUBLIC "html" "">
<html><body>
  <p>Testing
</p></body></html>

Надеюсь, это поможет,
Захари

0 голосов
/ 04 сентября 2011

XHTML - XML (если он действителен).

Чтобы ваш XHTML обрабатывался как XML, вы не должны использовать его как MIME "text / html". Вместо этого используйте application / xhtml + xml (имейте в виду, что IE6 не поддерживает рендеринг и будет отображать окно загрузки для вашего сайта).

В PHP вы используете его как xhtml + xml с функцией header().

Я думаю, что это должно сработать:

header('Content-Type: application/xhtml+xml');

Помогает ли это?

...