Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Xmltask запутался в dtd

Автор вопроса: skiphoppyОтветов: 5

Я пытаюсь использовать xmltask для ant для изменения файла в подкаталоге:

project/path/to/file.xml

Файл ссылается на DTD следующим образом:

<!DOCTYPE data SYSTEM "mydtd.dtd">

У меня нет возможности изменить эти документы.

Этот DTD хранится в том же подкаталоге, который всегда работал нормально:

project/path/to/mydtd.dtd

К сожалению, xmltask пытается найти dtd в каталоге верхнего уровня моего проекта, где находится мой файл сборки и откуда я запускаю:

[xmltask] java.io.FileNotFoundException: /home/me/project/mydtd.dtd (Система не может найти указанный файл)

Я вижу в документации xmltask, что могу исправить это с помощью элемента xmlcatalog, чтобы указать, где искать файл. Но мне нужно использовать элемент dtd, и я могу найти только примеры для этого элемента, а не документацию; в примерах показан только publicId, и, если я правильно понимаю XML, в этом документе его нет. В любом случае, мне не нужно указывать это, верно, поскольку в моем документе уже сказано, что мое DTD хранится локально, и показано, где оно находится?

Почему xmltask неправильно находит DTD? Каков наилучший способ исправить или обойти эту ситуацию?

antdtd

Ответы

Ответ 1 · рейтинг 5 · skaffman

Каталог XML - это то, что вам нужно, просто нужно немного больше настойчивости.

Как вы правильно заметили, стандартный тип Ant <XmlCatalog> позволяет вам указывать общедоступные ссылки DTD только при использовании встроенного синтаксиса, который вам не нужен. Однако <XmlCatalog> также позволяет указать стандартный каталог синтаксиса OASIS, который намного богаче, включая разрешение ссылок SYSTEM DTD.

Каталог OASIS (полная спецификация здесь) выглядит как это:

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
  <system systemId="mydtd.dtd" uri="project/path/to/mydtd.dtd"/>
</catalog>

Затем вы можете ссылаться на этот каталог из <XmlCatalog>:

<xmlcatalog refid="commonDTDs"/>
  <catalogpath>
    <pathelement location="path/to/oasis.catalog"/>
  </catalogpath>
</xmlcatalog>

И это все. Это хорошая идея создать повторно используемый файл каталога OASIS и ссылаться на него из различных связанных с XML задач Ant, каждая из которых может использовать <XmlCatalog>.

Ответ 2 · рейтинг 1 · skiphoppy

В качестве альтернативы, похоже, я могу пропустить всю проверку, создав пустой файл с тем же именем, что и файл DVD, а затем удалив файл, когда закончу. Скорее всего, я пойду по этому пути вместо того, чтобы пользоваться каталогом.

Ответ 3 · David M

xmltask не находит его, потому что ищет в текущем рабочем каталоге. Ant позволяет указать базовый каталог с помощью атрибута basedir элемента <target>. Поэтому я предлагаю вам попробовать это:

<target basedir="path/to" ...>
  <xmltask...
</target>

Мне кажется, что на самом деле проблема не в XML/DTD, а в том, чтобы заставить xmltask взаимодействовать с ними двумя так, как вы хотите.

Если это не удается, вы можете использовать задачу Ant Copy, чтобы скопировать XML и DTD в корневую папку перед обработкой с помощью xmltask, а затем скопировать обратно.

Ответ 4 · manji

Ты пытался:

<!DOCTYPE data SYSTEM "./path/to/mydtd.dtd">

? Или абсолютный путь?

Кроме того, вы можете найти <dtd> описание здесь.

Ответ 5 · MarcFasel

У меня была аналогичная проблема, когда файл XML имел тип документа со ссылкой на СИСТЕМУ, которую нельзя было изменить.

<!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd">

Сначала я пошел по пути и создал файл каталога с каталогом OASIS, как описано выше, но чтобы иметь возможность использовать внешние каталоги, мне пришлось включить Apache Commons Resolver 1.1 (resolver.jar) в путь к классам Ant. strong> (см. http://ant.apache.org/manual/Types/xmlcatalog.html а>).

Поскольку у меня было несколько машин, на которых эта сборка должна была работать, это казалось излишним, тем более что xmltask работал нормально, если я просто удалил определение типа документа. Мне не разрешили удалить его навсегда, потому что тип документа был нужен в другом месте.

В конечном итоге я использовал этот обходной путь: я закомментировал определение типа документа с помощью задачи Ant replace, запустил xmltask, а затем поместил тип документа обратно в файл.

<replace file="myxmlfile.xml">
    <replacetoken>&lt;!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"&gt;</replacetoken>
    <replacevalue>&lt;!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --&gt;</replacevalue>
</replace>

<xmltask .../>

<replace file="${local.opencms.webapp.webinf}/config/opencms-modules.xml">
    <replacetoken>&lt;!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --&gt;</replacetoken>
    <replacevalue>&lt;!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"&gt;</replacevalue>
</replace>

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы