如何在log4j.xml中使用DTD ENTITY外部引用

时间:2013-01-17 07:31:10

标签: java xml log4j dtd xml-dtd

我尝试使用外部dtd文件中的实体。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" 
[<!ENTITY logHome SYSTEM "log4j-entity.dtd">]
>

的log4j-entity.dtd

<?xml version="1.0" encoding="UTF-8"?>

<!ENTITY logHome "/root/crm_test/">

我尝试在这样的属性值中使用实体值。

<param name="File" value="&logHome;log/info.log"/>

我得到这个错误:

The external entity reference "&logHome;" is not permitted in an attribute value.

我该怎么做?

注意:

这件事有效..

<!ENTITY logHome  "/root/crm_test/">

3 个答案:

答案 0 :(得分:5)

您需要将内部子集中的实体作为参数实体,然后引用它。

变化:

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" 
[<!ENTITY logHome SYSTEM "log4j-entity.dtd">]
>

为:

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" [
<!ENTITY % logHome SYSTEM "log4j-entity.dtd">
%logHome;
]>

答案 1 :(得分:1)

XML规范明确禁止在属性值中使用外部实体。见这里:http://www.w3.org/TR/2004/REC-xml-20040204/#forbidden

  

以下内容被禁止,并构成致命错误:[...]在属性值中引用外部实体。

所以答案是:XML不会让你做你想做的事情。但是,如果您通过XSLT处理器运行XML并根据需要应用转换,则可能会产生类似的效果。

答案 2 :(得分:1)

这里有一些问题。

  1. 您正在使用实体名称logHome用于两个不同的事物(包含声明的外部实体,这应该是Daniel Haley指出的参数实体)和内部实体,其替换文本命名目录。
  2. 因此,您对属性值中&logHome;的引用被理解为对URI为“log4j-entity.dtd”的资源的引用。
  3. 实现您想要的最简单方法是在内部子集中声明logHome实体:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" [
    <!ENTITY logHome "/root/crm_test/">
    ]>
    

    如果你真的希望logHome的声明是外部的,那么为参数实体使用不同的名称可能不那么令人困惑:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" [
    <!ENTITY % logHomeDeclaration SYSTEM "log4j-entity.dtd">
    %logHomeDeclaration;
    ]>