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

我得到这个错误:

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

我怎样才能做到这一点?

笔记:

这东西行得通。。

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

3 回答 3

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;
]>
于 2013-01-17T09:07:26.117 回答
1

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

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

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

于 2013-01-17T07:39:20.893 回答
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;
]>
于 2013-01-19T01:11:50.590 回答