2016-01-05 11 views
8

Ich brauche eine benutzerdefinierte XML-Datei zu erstellen, in meinem Android-Anwendung verwendet werden,Android: XML-Datei zur Kompilierzeit validieren?

die Datei einige benutzerdefinierte Objekte enthalten, die in meiner Anwendung benötigt werden,

Ich verstehe, dass die ich brauche sie setzen in die res\xml oder res\raw. OK.


Nun würde Ich mag bei der Kompilierung benachrichtigt werden, wenn etwas in der XLM falsch ist:

zum Beispiel:

nehme an, ich möchte über XML Katzen definieren:

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

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

Ich würde gerne wissen, ob es möglich ist, eine Kompilierzeit Warnung zu bekommen, wenn ich so etwas tue:

(wo Bellen nicht etwas, das ich meine Katzen definiert haben tun können):

<cats> 
    <persian-cat 
     barks="true" 
     fur="short" 
     tail="5" /> 
</cats> 

Ist das möglich?

Bitte wie kann ich es erreichen?

Antwort

4

Folgendes funktioniert auf dem Gradle-Build-System.

Definieren Sie zuerst ein Xml-Schema (XSD) -Dokument, das genau angibt, wie die Struktur des XML-Dokuments aussehen soll. Zum Beispiel in einer Datei 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> 

In obigem Beispiel gibt XSD-Dokument, dass wir nur <animal> Tags mit nur drei Attributen haben: Name, Alter und Ton. Auch Datentypen dieser Attribute wurden streng definiert. Wenn Sie XML-Schemas nicht kennen, können Sie einige online documentation lesen.

Erstellen Sie als Nächstes ein XML-Dokument, das dem obigen Schema folgen soll, indem Sie als Schema auf text.xsd verweisen.Zum Beispiel in einer Datei 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> 

Wie Sie sehen können, haben wir hinzugefügt absichtlich einen Tag <cat>, die dort nicht in der Schema-Definition ist, dass wir gerade definiert haben.

If you are using Android Studio, it will automatically lookup the schema file and provide auto-complete, as well as highlight schema errors when editing the XML file.

Aber der Zweck ist das XML-Dokument mit XSD-Schema zu validieren, baut jedes Mal Gradle das Android-Projekt. Also definieren wir eine benutzerdefinierte Gradle-Aufgabe, um dies zu tun. Zum Beispiel in 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)); 
} 

Hier verwenden wir Java XML API einige groovy Code zu schreiben, die beide Dateien liest und überprüft die XML-Datei XSD-Datei. Sie können nun diese Aufgabe von Gradle CLI ausführen:

Zum Beispiel:

./gradlew validateXml 

Es wird fehlschlagen, mit dem Fehler:

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. 

Großen. Jetzt wollen wir die validateXml Aufgabe jede Zeit ausführen, die das Projekt gebaut wird. Genauer gesagt, wenn Dateien gepackt werden. So fügen wir eine weitere Zeile zu Gradle-Datei erstellen (nach der Definition validateXml Aufgabe):

assemble.dependsOn validateXml; 

Nun wird assemble Aufgabe validateXml ruft automatisch auf zu bauen.

In Zukunft können Sie einfach die XSD-Datei aktualisieren, um neue Regeln für die XML-Datei anzuwenden.

+0

das ist wirklich toll, danke! –

1

Android Lint benutzerdefinierte Regeln zur Rettung. Sie können Ihre benutzerdefinierte Flusenregel wie beschrieben here erstellen und Prüfungen vor jedem Build ausführen. Wenn etwas mit Ihrer benutzerdefinierten XML-Datei nicht stimmt, werden Sie in der Konsole benachrichtigt.

+0

noch bessere Idee! –

1

Vorschlag: Wenden Sie sich an Unit Tests.

Sie können Produktionscode erstellen, der die Integrität Ihrer XML-Datei überprüft (z. B. durch Ausführen eines Parsers, einschließlich Schemaüberprüfung). dann führen Sie diesen Code nur in bestimmten Komponententests aus. (Offensichtlich ist es ein bisschen komplizierter; man muss sorgfältig studieren, was für Sie am sinnvollsten ist; aber gut, wir machen etwas Ähnliches, und es erweist sich als äußerst hilfreich).

Nicht genau "Kompilierzeit", aber nahe - da viele IDEs bestimmte Komponententests beim Ändern bestimmter Dateien ausführen können. Und natürlich sind Ihre Komponententests dann Teil Ihrer Komponententest-Regression.

+0

Guter Vorschlag, danke! –

Verwandte Themen