如何在 DTD 中将 ATTLIST 与 EMPTY 元素一起使用

How do I use ATTLIST with an EMPTY element in DTD

我有以下 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, "TRUE", "0" },
                { "type", "VALIDATE_TYPE", "String", null, null, null, null },
                { "description", "VALIDATE_DESCRIPTION", "String", null, null, null, null },
                { "activeYN", "VALIDATE_ACTIVEYN", "Boolean", null, null, null, null },
                { "oldCode", "VALIDATE_OLDCODE", "String", null, null, null, null },
                { "keyCode", "VALIDATE_KEYCODE", "String", null, null, null, 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", "Validate");
        method.setAttribute("returns-collection", "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", "String");
        parameter.setAttribute("sequence", "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>