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

4
我尝试使用外部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"/>

I get this errror:

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

我该如何做到这一点?

注意:

这个东西有效。

<!ENTITY logHome  "/root/crm_test/">
3个回答

5
您需要将内部子集中的实体变为参数实体,然后引用它。
更改:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" 
[<!ENTITY logHome SYSTEM "log4j-entity.dtd">]
>

to:

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

1

这里有几个问题。

  1. 您正在使用实体名称logHome来表示两个不同的事物(一个包含声明的外部实体,应该像Daniel Haley指出的那样成为参数实体,以及一个替换文本命名目录的内部实体)。
  2. 因此,在属性值中对&logHome;的引用被理解为对URI为“log4j-entity.dtd”的资源的引用。

实现您想要的最简单的方法是在内部子集中声明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;
]>

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

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

因此答案是:XML不允许您尝试做的事情。但是,如果您通过XSLT处理器运行XML并根据需要应用转换,则可能会获得类似的效果。

我认为OP是无意中引用了一个外部实体。他/她真正想引用的实体不是外部实体。这在XML中是可能的。 - Daniel Haley
啊,是的,那确实有道理。 - Magnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接