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

Я пытаюсь использовать 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? Каков наилучший способ исправить или обойти эту ситуацию?


person skiphoppy    schedule 29.09.2009    source источник


Ответы (5)


Каталог 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>.

person skaffman    schedule 08.01.2010

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

person skiphoppy    schedule 02.02.2010

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

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

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

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

person David M    schedule 08.01.2010
comment
Использование относительных ссылок SYSTEM таким образом является плохой практикой, поскольку их разрешение затруднено. Исходные документы должны использовать либо ПУБЛИЧНЫЕ ссылки, либо абсолютные СИСТЕМНЫЕ ссылки. К счастью, каталоги XML (при правильном применении) могут обойти этот плохой дизайн. - person skaffman; 11.01.2010

Ты пытался:

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

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

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

person manji    schedule 29.09.2009
comment
Это разрушило бы всю остальную обработку этих документов, поскольку при развертывании они находятся рядом со своими dtd, но не в том же каталоге, где я пытаюсь редактировать их во время сборки. - person skiphoppy; 29.09.2009
comment
В вопросе говорится, что у меня нет возможности изменять эти документы. - person skaffman; 11.01.2010
comment
@skaffman, честно говоря, когда я изначально спрашивал, этого не было сказано, и я добавил это из-за этого ответа. :) - person skiphoppy; 11.01.2010
comment
О, достаточно справедливо. Извините, @najmeddine :) - person skaffman; 11.01.2010

У меня была аналогичная проблема, когда файл 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>
person MarcFasel    schedule 15.05.2013