Android cannot validate XML with XSD. WTF

This commit is contained in:
paul-loedige 2020-12-27 19:47:47 +01:00
parent 41c757b7b2
commit dbb108a459
5 changed files with 54 additions and 56 deletions

4
APED/.idea/gradle.xml generated
View File

@ -10,8 +10,8 @@
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$USER_HOME$/Storage/Programs/TH/MO_Mobile_Systeme/aped_app/APED" />
<option value="$USER_HOME$/Storage/Programs/TH/MO_Mobile_Systeme/aped_app/APED/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />

@ -1 +1 @@
Subproject commit ce8ce41609a1a7ef9282cbcdda3358f9c2ec6939
Subproject commit 594fc1ea61264673706a2e26120e3b4b95af4f2f

View File

@ -2,7 +2,9 @@ package com.example.aped;
import android.Manifest;
import android.app.AlertDialog;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MenuItem;
@ -10,8 +12,10 @@ import android.view.Menu;
import android.widget.Toast;
import com.example.aped.communication.IIO;
import com.example.aped.utils.ExternalStorageHandler;
import com.example.aped.utils.IXML;
import com.example.aped.utils.TestXML;
import com.example.aped.utils.XMLHandler;
import com.google.android.material.navigation.NavigationView;
import androidx.annotation.NonNull;
@ -25,6 +29,16 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class MainActivity extends AppCompatActivity {
@ -42,6 +56,7 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
//checks that the permission to read and write the xml is granted
ensurePermissions();
setXML();
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@ -59,8 +74,6 @@ public class MainActivity extends AppCompatActivity {
NavigationUI.setupActionBarWithNavController(this,
navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
xml = new TestXML();
}
/** Fügt Elemente zur Aktionsleiste hinzu, wenn diese vorhanden ist.*/
@Override
@ -117,13 +130,7 @@ public class MainActivity extends AppCompatActivity {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PERMISSION_GRANTED) {
Toast.makeText(
this,
"You have already granted this permission",
Toast.LENGTH_LONG)
.show();
} else {
!= PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
@ -176,4 +183,29 @@ public class MainActivity extends AppCompatActivity {
}
}
}
private void setXML(){
try {
String xmlPath = ExternalStorageHandler.getExternalPrivateStorageDir(MainActivity.this);
File xmlFile = new File(xmlPath,"config.xml");
//create the default XML config by using the default.xml from the assets folder
if (xmlFile.exists()){
xmlFile.delete();
}
InputStream inputStream = getAssets().open("XML/default.xml");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
FileOutputStream fileOutputStream = new FileOutputStream(xmlFile);
fileOutputStream.write(buffer);
fileOutputStream.close();
xml = new XMLHandler(xmlFile);
} catch (FileNotFoundException e) {
Log.e("Main Activity","Exception while reading the external private storage dir: " + e.getMessage());
} catch (ParserConfigurationException | IOException | SAXException e){
Log.e("Main Activity","XMLHandler failed to initialise: " + e.getMessage());
}
}
}

View File

@ -15,14 +15,9 @@ import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
@ -38,44 +33,17 @@ public class XMLHandler implements IXML {
/**
* constructor for the XMLHandler.
* @param xmlPath the path to the XML file
* @param xsdPath the path to the XSD file
* @param xmlFile the XML file
* @throws ParserConfigurationException the XML parser configuration failed
* @throws IOException the XML file could not be accessed
* @throws SAXException the XML parse failed
*/
public XMLHandler(final String xmlPath, final String xsdPath)
public XMLHandler(final File xmlFile)
throws ParserConfigurationException, IOException, SAXException {
if (!validate(xmlPath, xsdPath)) {
throw new VerifyError("the XML file is invalid");
}
//parse the root document fromt the XML file
//parse the root document from the XML file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
root = builder.parse(new File(xmlPath));
}
/**
* validates a XML file against a XSD file.
* @param xmlPath the path to the XML file
* @param xsdPath the path to the XSD file
* @return true if XML is valid
*/
private boolean validate(final String xmlPath, final String xsdPath) {
try {
SchemaFactory factory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI
);
Schema schema = factory.newSchema(new File(xsdPath));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(xmlPath)));
} catch (IOException | SAXException e) {
Log.e("XMLHandler",
"Error while validating the XML file"
+ e.getMessage());
return false;
}
return true;
root = builder.parse(xmlFile);
}
@Override

View File

@ -16,14 +16,12 @@ import static org.junit.Assert.*;
public class XMLHandlerUnitTest {
private String xmlPath="src/main/assets/XML/Test.xml";
private String xsdPath="src/main/assets/XML/config.xsd";
private File xmlFile = new File(xmlPath);
private File xsdFile = new File(xsdPath);
@Test
public void TestFiles_AreValid(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
}catch(IOException | ParserConfigurationException | SAXException e){
System.out.println("XMLHandler failed");
assert(false);
@ -36,7 +34,7 @@ public class XMLHandlerUnitTest {
@Test
public void Test_getDeviceNames(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
List<String> deviceNames = xmlHandler.getDeviceNames();
assertArrayEquals(new String[]{"example","sensorarray"},deviceNames.toArray());
}catch(IOException | ParserConfigurationException | SAXException e){
@ -48,7 +46,7 @@ public class XMLHandlerUnitTest {
@Test
public void TestInput_SimpleValueInfo(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
Dictionary<String, Object> valueInfo = xmlHandler.getValueInfo("example");
assertEquals("{factor=1.0, type=boolean, unit=, offset=0.0}",valueInfo.toString());
}catch(IOException | ParserConfigurationException | SAXException e){
@ -60,7 +58,7 @@ public class XMLHandlerUnitTest {
@Test
public void TestInput_ComplexValueInfo(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
Dictionary<String, Object> valueInfo = xmlHandler.getValueInfo("sensorarray");
assertEquals("{factor=2.5, type=int, unit=°C, offset=1.2}",valueInfo.toString());
}catch(IOException | ParserConfigurationException | SAXException e){
@ -72,7 +70,7 @@ public class XMLHandlerUnitTest {
@Test
public void TestInput_SimplePort(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
Dictionary<String, Object> port = xmlHandler.getPort("example");
assertEquals("{pins=[GPIO_2], protocol=DI}",port.toString());
}catch(IOException | ParserConfigurationException | SAXException e){
@ -84,7 +82,7 @@ public class XMLHandlerUnitTest {
@Test
public void TestInput_ComplexPort(){
try{
XMLHandler xmlHandler = new XMLHandler(xmlFile,xsdFile);
XMLHandler xmlHandler = new XMLHandler(xmlFile);
Dictionary<String, Object> port = xmlHandler.getPort("sensorarray");
assertEquals("{pins=[GPIO_3, GPIO_4, GPIO_5, GPIO_6], protocol=DI}",port.toString());
}catch(IOException | ParserConfigurationException | SAXException e){