【问题标题】:xmltask confused about dtdxmltask 对 dtd 感到困惑
【发布时间】:2010-12-02 08:04:15
【问题描述】:

我正在尝试使用 xmltask for 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?纠正或解决这种情况的最佳方法是什么?

【问题讨论】:

    标签: ant dtd


    【解决方案1】:

    你试过了吗:

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

    ?还是绝对路径?

    另外,您可以找到&lt;dtd&gt; 描述here

    【讨论】:

    • 这会破坏对这些文档的所有其他处理,因为当它们被部署时,它们与 dtds 并排放置,但不在我试图在构建时编辑它们的同一目录中。
    • 问题是“我没有更改这些文档的灵活性。”
    • @skaffman,公平地说,当我最初询问时并没有这么说,因为这个答案我添加了它。 :)
    • 哦,很公平。对不起,@najmeddine :)
    【解决方案2】:

    xmltask 没有找到它,因为它正在当前工作目录中查找。 Ant 允许您使用&lt;target&gt; 元素的basedir 属性指定基本目录。所以我建议你试试这个:

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

    令我震惊的是,您真正遇到问题的不是 XML/DTD,而是让 xmltask 随心所欲地与它们两者进行交互。

    如果失败,您可以使用 Ant Copy 任务将 XML 和 DTD 复制到根文件夹,然后再使用 xmltask 进行处理,然后再次复制回来。

    【讨论】:

    • 以这种方式使用相对 SYSTEM 引用是不好的做法,因为解决它们很困难。源文档应使用 PUBLIC 引用或绝对 SYSTEM 引用。值得庆幸的是,XML 目录(正确应用)可以绕过这种糟糕的设计。
    【解决方案3】:

    XML 目录是通往这里的路,它只是需要更多的毅力。

    正如您正确指出的那样,标准 Ant &lt;XmlCatalog&gt; 类型仅允许您在使用内联语法时指定公共 DTD 引用,这对您没有用处。但是,&lt;XmlCatalog&gt; 还允许您指定一个标准的 OASIS 语法目录,该目录要丰富得多,包括解析 SYSTEM DTD 引用。

    OASIS 目录(完整规范 here)如下所示:

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

    然后您可以从&lt;XmlCatalog&gt; 引用此目录:

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

    就是这样。建立一个可重用的 OASIS 目录文件是一个好主意,并从各种 XML 相关的 Ant 任务中引用它,所有这些都可以使用 &lt;XmlCatalog&gt;

    【讨论】:

      【解决方案4】:

      作为替代方案,我似乎可以通过创建一个与 DVD 文件同名的空白文件来跳过整个验证,然后在完成后删除该文件。我很可能会走那条路而不是使用目录。

      【讨论】:

        【解决方案5】:

        我遇到了一个类似的问题,即 XML 文件的 doctype 带有无法更改的 SYSTEM 引用。

        &lt;!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"&gt;

        我首先按照上述方法使用 OASIS 目录创建了一个目录文件,但是为了能够使用外部目录,我必须在 Ant 中包含 Apache Commons Resolver 1.1 (resolver.jar)类路径(参见http://ant.apache.org/manual/Types/xmlcatalog.html)。

        因为我有多台机器应该运行这个构建,这似乎有点过头了,特别是因为如果我刚刚删除了 doctype 定义,xmltask 工作得很好。不允许我永久删除它,因为其他地方需要该文档类型。

        最终我使用了这个解决方法:我使用 Ant 的 replace 任务注释掉了 doctype 定义,运行了 xmltask,然后将 doctype 放回文件中。

        <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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-13
          • 2012-07-22
          • 2013-05-13
          • 2020-04-16
          • 2023-03-08
          • 2019-08-04
          • 2019-12-30
          • 2022-01-20
          相关资源
          最近更新 更多