Java 中是否有与 Ruby 中的 Nokogiri::XML::EntityDecl 等价的东西?

Is there some equivalent in Java to Ruby's Nokogiri::XML::EntityDecl?

我遇到一个问题,我需要在现有 XML 文档中添加包含定义中括起来的实体的 DTD。

例如,根据 http://www.daisy.org/projects/mathml/mathml-in-daisy-spec.html 的 DAISY 中的 MathML 规范工作,假设我从外部来源获得此 XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dtbook PUBLIC "-//NISO//DTD dtbook 2005-2//EN"
 "http://www.daisy.org/z3986/2005/dtbook-2005-2.dtd">
<dtbook xmlns="http://www.daisy.org/z3986/2005/dtbook/" xmlns:m="http://www.w3.org/1998/Math/MathML"
    version="2005-3" xml:lang="eng">
    <m:math xmlns:dtbook="http://www.daisy.org/z3986/2005/dtbook/"
  id="math0001" dtbook:smilref="nativemathml.smil#math0001"
  altimg="nativemathml0001.png"
  alttext="sigma-summation UnderScript i equals zero OverScript infinity EndScripts x Subscript i">
      <m:mrow>
        <m:mstyle displaystyle='true'>
          <m:munderover>
            <m:mo>&#x2211;</m:mo>
            <m:mrow>
              <m:mi>i</m:mi><m:mo>=</m:mo><m:mn>0</m:mn>
            </m:mrow>
            <m:mi>&#x221E;</m:mi>
          </m:munderover>
          <m:mrow>
            <m:msub>
              <m:mi>x</m:mi>
              <m:mi>i</m:mi>
            </m:msub>
          </m:mrow>
        </m:mstyle>
      </m:mrow>
</m:math>
</dtbook>

我想添加规范中的 ENTITY 定义,使本书支持 MathML,结果如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dtbook PUBLIC "-//NISO//DTD dtbook 2005-2//EN"
 "http://www.daisy.org/z3986/2005/dtbook-2005-2.dtd"
 [
  <!ENTITY % MATHML.prefixed "INCLUDE" >
  <!ENTITY % MATHML.prefix "m">
  <!ENTITY % MATHML.Common.attrib
          "xlink:href    CDATA       #IMPLIED
          xlink:type     CDATA       #IMPLIED
          class          CDATA       #IMPLIED
          style          CDATA       #IMPLIED
          id             ID          #IMPLIED
          xref           IDREF       #IMPLIED
          other          CDATA       #IMPLIED
          xmlns:dtbook   CDATA       #FIXED 'http://www.daisy.org/z3986/2005/dtbook/'
          dtbook:smilref CDATA       #IMPLIED"
  >
  <!ENTITY % mathML2 PUBLIC "-//W3C//DTD MathML 2.0//EN"
             "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd"
  >
  %mathML2;
  <!ENTITY % externalFlow "| m:math">
  <!ENTITY % externalNamespaces "xmlns:m CDATA #FIXED
    'http://www.w3.org/1998/Math/MathML'">
 ]
>
<dtbook xmlns="http://www.daisy.org/z3986/2005/dtbook/" xmlns:m="http://www.w3.org/1998/Math/MathML"
    version="2005-3" xml:lang="eng">
    <m:math xmlns:dtbook="http://www.daisy.org/z3986/2005/dtbook/"
  id="math0001" dtbook:smilref="nativemathml.smil#math0001"
  altimg="nativemathml0001.png"
  alttext="sigma-summation UnderScript i equals zero OverScript infinity EndScripts x Subscript i">
      <m:mrow>
        <m:mstyle displaystyle='true'>
          <m:munderover>
            <m:mo>&#x2211;</m:mo>
            <m:mrow>
              <m:mi>i</m:mi><m:mo>=</m:mo><m:mn>0</m:mn>
            </m:mrow>
            <m:mi>&#x221E;</m:mi>
          </m:munderover>
          <m:mrow>
            <m:msub>
              <m:mi>x</m:mi>
              <m:mi>i</m:mi>
            </m:msub>
          </m:mrow>
        </m:mstyle>
      </m:mrow>
</m:math>
</dtbook>

在Ruby中,Nokogiri 中有一个方法可以用来添加这些实体定义,如下所示: Nokogiri::XML::EntityDecl.new("MATHML.prefixed", doc, MATHML_ENTITY_DECL_TYPE, nil, nil, "INCLUDE")

在 Java 中是否有与此等效的内容?我们正在使用 JDOM 来操作我们的 XML 文档,但是 JDOM DocType class 似乎不支持这些实体定义。

使用 JDOM,您应该能够解析原始文档,并从文档中提取 DTDContent 节点。

您的代码将类似于:

Document doc = saxBuilder.build(myxmlfile);
DocType dtd = doc.getDocType();

dtd内容应该是对dtbook引用的引用。

您现在可以采用 mathml 声明的字符串表示形式,并将它们包含为 DocType 的内部子集(也许您想从文件中读取它,或者作为系统资源或其他内容)。

String internal = "  <!ENTITY % MATHML.prefixed \"INCLUDE\" >\n"
    + "  <!ENTITY % MATHML.prefix \"m\">\n"
    + ......

dtd.setInternalSubset(internal);

参见:http://www.jdom.org/docs/apidocs/org/jdom2/DocType.html#setInternalSubset(java.lang.String)

这将修改声明,如果你输出XML,你应该有你期望的内容:

XMLOutputter xout = new XMLOutputter();
xout.output(doc, System.out);