Android:在编译时验证xml文件?

Lis*_*nne 8 java xml android

我需要创建一个自定义XML文件,以便在我的Android应用程序中使用,

该文件将包含我的应用程序所需的一些自定义对象,

我明白我需要将它们放入res\xml或中res\raw.好.


现在,如果XLM出现问题,我希望在编译时得到通知:

例如:

假设我想通过XML定义猫:

<cats>
    <siamese-cat
        fur="short"
        tail="5" />

    <persian-cat
        fur="short"
        tail="5" />
</cats>
Run Code Online (Sandbox Code Playgroud)

我想知道如果我做这样的事情是否有可能得到编译时警告:

(吠叫不是我定义的猫可以做的事情):

 <cats>
    <persian-cat
        barks="true"
        fur="short"
        tail="5" />
</cats>
Run Code Online (Sandbox Code Playgroud)

那可能吗?

请问我该如何实现?

S.D*_*.D. 5

以下内容适用于gradle构建系统.

首先,定义一个Xml Schema(XSD)文档,该文档准确指定XML文档的结构.例如,在文件中test.xsd:

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
    <xs:element name="animals">
        <xs:complexType>
            <xs:sequence minOccurs="0">
                <xs:element name="animal">
                    <xs:complexType>
                        <xs:attribute name="name" type="xs:string"/>
                        <xs:attribute name="age" type="xs:int"/>
                        <xs:attribute name="sound" type="xs:string"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,XSD文档指定我们只能<animal>包含只有3个属性的标记:名称,年龄和声音.此外,还严格定义了这些属性的数据类型.如果您不熟悉XML模式,可以阅读一些在线文档.

接下来,通过引用text.xsd作为其模式,创建一个应该遵循上述模式的XML文档.例如,在文件中test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation='test.xsd'>
    <animal name="kitty" age="2" sound="meow"/>
    <cat name="bad_cat"></cat>
</animals>
Run Code Online (Sandbox Code Playgroud)

如您所见,我们故意添加了一个标记<cat>,我们刚刚定义的模式定义中没有这个标记.

如果您使用的是Android Studio,它将自动查找架构文件并提供自动完成,以及在编辑XML文件时突出显示架构错误.

但目的是每次Gradle构建android项目时,使用XSD架构验证XML文档.因此,我们定义了一个自定义Gradle任务来执行此操作.例如,在build.gradle:

import javax.xml.XMLConstants
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory

task validateXml {
    File xml = new File('./test.xml');
    File xsd = new File('./test.xsd');

    def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    def schema = factory.newSchema(xsd);
    def validator = schema.newValidator();
    validator.validate(new StreamSource(xml));
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用Java XML API编写一些groovy代码,这些代码读取这两个文件并使用XSD文件验证XML文件.您现在可以从Gradle CLI运行此任务:

例如:

./gradlew validateXml
Run Code Online (Sandbox Code Playgroud)

它将失败,错误:

A problem occurred evaluating root project 'Bad Cats'.
> cvc-complex-type.2.4.d: Invalid content was found starting with element 'cat'. No child element is expected at this point.
Run Code Online (Sandbox Code Playgroud)

大.现在我们希望每次构建项目时都validateXml运行任务.更具体地说,当打包文件时.因此,我们向Gradle构建文件添加一行(在定义任务之后):validateXml

assemble.dependsOn validateXml;
Run Code Online (Sandbox Code Playgroud)

现在,assemble任务将validateXml在构建时自动调用.

将来,您可以更新XSD文件以应用XML文件的新规则.