如何在 DTD 中使用带有 EMPTY 元素的 ATTLIST

问题描述

我有以下 DTD 和 XML 文件。当我尝试验证文件时,出现以下错误。很明显,第 6 行的 xml 是一个标签。我在网上找到了几个带有 ATTLIST 的 EMPTY ELEMENTS 的例子。我做错了什么?

org.xml.sax.SAXParseException; systemId: file:///C:/tdc-to-xml/ejb.xml;行号:6;列数:145;元素类型“field”的内容不完整,必须匹配“(EMPTY)”。

DTD

<!ELEMENT kds-ejb (entities,methods)>
<!ELEMENT entities (entity+)>
<!ELEMENT entity (field+)>
<!ATTLIST entity name CDATA #required>
<!ATTLIST entity db-name CDATA #required>
<!ATTLIST entity sequence-name CDATA #IMPLIED>
<!ATTLIST entity is-audited (TRUE|FALSE) "FALSE">
<!ELEMENT field (EMPTY)>
<!ATTLIST field name CDATA #required>
<!ATTLIST field db-name CDATA #required>
<!ATTLIST field java-type CDATA #required>
<!ATTLIST field is-auto-generated (TRUE|FALSE) "FALSE">
<!ATTLIST field is-audited (TRUE|FALSE) "FALSE">
<!ATTLIST field is-primary-key (TRUE|FALSE) "FALSE">
<!ATTLIST field primary-key-sequence CDATA #IMPLIED>
<!ELEMENT methods (method+)>
<!ELEMENT method (sql,parameters,code?)>
<!ATTLIST method name CDATA #required>
<!ATTLIST method entity-name CDATA #IMPLIED>
<!ATTLIST method returns-collection (TRUE|FALSE) "FALSE">
<!ATTLIST method special-return-type CDATA #IMPLIED>
<!ELEMENT sql (#PCDATA)>
<!ELEMENT parameters (parameter)>
<!ELEMENT parameter (EMPTY)>
<!ATTLIST parameter name CDATA #required>
<!ATTLIST parameter java-type CDATA #required>
<!ATTLIST parameter special-return-type CDATA #IMPLIED>
<!ELEMENT code (line+)>
<!ELEMENT line (text+)>
<!ATTLIST line sequence CDATA #required>
<!ELEMENT text (#PCDATA)>

XML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE kds-ejb PUBLIC "-//Genera//DTD XML EJB 1.0//EN" "ejb.v1.dtd">
<kds-ejb>
    <entities>
        <entity db-name="tblValidate" name="Validate">
<!-- the following line is line 6 -->
            <field db-name="VALIDATE_ID" is-auto-generated="TRUE" is-primary-key="TRUE" java-type="Integer" name="id" primary-key-sequence="0"/>
            <field db-name="VALIDATE_TYPE" java-type="String" name="type"/>
            <field db-name="VALIDATE_DESCRIPTION" java-type="String" name="description"/>
            <field db-name="VALIDATE_ACTIVEYN" java-type="Boolean" name="activeYN"/>
            <field db-name="VALIDATE_OLDCODE" java-type="String" name="oldCode"/>
            <field db-name="VALIDATE_KEYCODE" java-type="String" name="keyCode"/>
        </entity>
    </entities>
    <methods>
        <method entity-name="Validate" name="getValidateByType" returns-collection="TRUE">
            <sql>SELECT * FROM TBLVALIDATE WHERE VALIDATE_TYPE = :type ORDER BY VALIDATE_DESCRIPTION</sql>
            <parameters>
                <parameter java-type="String" name="oldCode" sequence="0"/>
            </parameters>
        </method>
        <method entity-name="Validate" name="getValidateByOldCode" returns-collection="FALSE">
            <sql>SELECT * FROM TBLVALIDATE WHERE VALIDATE_OLDCODE = :oldCode</sql>
            <parameters>
                <parameter java-type="String" name="type" sequence="0"/>
            </parameters>
        </method>
    </methods>
</kds-ejb>

用于创建 xml 和验证的代码

public class TdcToXml {
private String fileName = null;

public TdcToXml(String fileName) {
    this.fileName = fileName;
}

private void process() {
    try {

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

        Document doc = docBuilder.newDocument();
        Element rootElement = doc.createElement("kds-ejb");
        doc.appendChild(rootElement);

        Element entities = doc.createElement("entities");
        rootElement.appendChild(entities);

        Element entity = doc.createElement("entity");
        entity.setAttribute("name","Validate");
        entity.setAttribute("db-name","tblValidate");
        entities.appendChild(entity);

        String[][] fields = { { "id","VALIDATE_ID","Integer","TRUE",null,"0" },{ "type","VALIDATE_TYPE","String",null },{ "description","VALIDATE_DESCRIPTION",{ "activeYN","VALIDATE_ACTIVEYN","Boolean",{ "oldCode","VALIDATE_OLDCODE",{ "keyCode","VALIDATE_KEYCODE",null } };
        for (String[] singleField : fields) {
            Element field = doc.createElement("field");
            field.setAttribute("name",singleField[0]);
            field.setAttribute("db-name",singleField[1]);
            field.setAttribute("java-type",singleField[2]);
            if (singleField[3] != null)
                field.setAttribute("is-auto-generated",singleField[3]);
            if (singleField[4] != null)
                field.setAttribute("is-audited",singleField[4]);
            if (singleField[5] != null)
                field.setAttribute("is-primary-key",singleField[5]);
            if (singleField[6] != null)
                field.setAttribute("primary-key-sequence",singleField[6]);
            entity.appendChild(field);
        }

        Element methods = doc.createElement("methods");
        rootElement.appendChild(methods);

        Element method = doc.createElement("method");
        methods.appendChild(method);
        method.setAttribute("name","getValidateByType");
        method.setAttribute("entity-name","Validate");
        method.setAttribute("returns-collection","TRUE");
        methods.appendChild(method);

        Element sql = doc.createElement("sql");
        sql.appendChild(doc.createTextNode(
                "SELECT * FROM TBLVALIDATE WHERE VALIDATE_TYPE = :type ORDER BY VALIDATE_DESCRIPTION"));
        method.appendChild(sql);

        Element parameters = doc.createElement("parameters");
        method.appendChild(parameters);

        Element parameter = doc.createElement("parameter");
        parameter.setAttribute("name","oldCode");
        parameter.setAttribute("java-type","String");
        parameter.setAttribute("sequence","0");
        parameters.appendChild(parameter);

        method = doc.createElement("method");
        methods.appendChild(method);
        method.setAttribute("name","getValidateByOldCode");
        method.setAttribute("entity-name","FALSE");
        methods.appendChild(method);

        sql = doc.createElement("sql");
        sql.appendChild(doc.createTextNode("SELECT * FROM TBLVALIDATE WHERE VALIDATE_OLDCODE = :oldCode"));
        method.appendChild(sql);

        parameters = doc.createElement("parameters");
        method.appendChild(parameters);

        parameter = doc.createElement("parameter");
        parameter.setAttribute("name","type");
        parameter.setAttribute("java-type","0");
        parameters.appendChild(parameter);

        // write the content into xml file
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new File(fileName));

        DOMImplementation domImpl = doc.getImplementation();
        DocumentType doctype = domImpl.createDocumentType("doctype","-//Genera//DTD XML EJB 1.0//EN","ejb.v1.dtd");
        transformer.setoutputProperty(OutputKeys.DOCTYPE_PUBLIC,doctype.getPublicId());
        transformer.setoutputProperty(OutputKeys.DOCTYPE_SYstem,doctype.getSystemId());
        transformer.setoutputProperty(OutputKeys.INDENT,"yes");
        transformer.setoutputProperty("{http://xml.apache.org/xslt}indent-amount","4");
        transformer.transform(source,result);

        System.out.println("File saved!");

    } catch (ParserConfigurationException pce) {
        pce.printstacktrace();
    } catch (TransformerException tfe) {
        tfe.printstacktrace();
    }
}

private void validate() {
    try {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setValidating(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void error(SAXParseException exception) throws SAXException {
                // do something more useful in each of these handlers
                exception.printstacktrace();
            }

            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                exception.printstacktrace();
            }

            @Override
            public void warning(SAXParseException exception) throws SAXException {
                exception.printstacktrace();
            }
        });
        builder.parse(fileName);
    } catch (ParserConfigurationException pce) {
        pce.printstacktrace();
    } catch (SAXException e) {
        e.printstacktrace();
    } catch (IOException e) {
        e.printstacktrace();
    }
}

public static void main(String[] args) {
    TdcToXml tdcToXml = new TdcToXml("ejb.xml");
    tdcToXml.process();
    tdcToXml.validate();
}

}

解决方法

您可能需要删除“(EMPTY)”周围的括号。

对于括号,它期待一个名为“EMPTY”的元素。

应该是:

<!ELEMENT field EMPTY>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...