Skip to content

Commit 851089c

Browse files
committed
2_xsd_validate
1 parent cc61ccf commit 851089c

7 files changed

Lines changed: 135 additions & 3 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,20 @@ shell:>help help - info about help
5656
- [Лекции по XML](http://genberm.narod.ru/xml/lections.html)
5757

5858
Схему можно сгенерировать в IDEA (в контекстном меню в xml файле -> _Generate XSD Schema from XML File..._) и поправить вручную
59+
60+
## Validate XML files against XSD (XML Schema)
61+
> commit: 2_xsd_validate
62+
63+
- Создем общий класс класс `Schemas` (его можно использовать в своих приложениях без изменений) и специфичный для нашего приложения `SchemaUtil`
64+
- Вызываем `SchemaUtil.validate` из `Commands` и в каталоге `scr\test` создаем тесты
65+
- Для запуска JUnit тестов прямо [в IDEA ниже версии 2023.2](https://youtrack.jetbrains.com/issue/IDEA-231927) в pom требуется добавить `junit-platform-launcher`
66+
67+
- [Validate an XML File Against an XSD File](https://www.baeldung.com/java-validate-xml-xsd)
68+
69+
```
70+
shell:>help xsd
71+
shell:>xsd -i in/usersWithMeals.xml -s in/usersWithMeals.xsd
72+
shell:>xsd -i in/badXmlFile.xml -s in/usersWithMeals.xsd
73+
```
74+
75+
## [Process XML file via JAXB](https://javaops.ru/view/docjava/jaxb)

in/badXmlFile.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<UsersWithMeals xmlns="http://javaops.ru"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://javaops.ru usersWithMeals.xsd">
5+
<Users>
6+
<User enabled="true" caloriesPerDay="2005" name="User"
7+
password="password" registered="2023-01-01T13:00:00" roles="user">
8+
<Meals>
9+
<Meal calories="500" dateTime="2023-01-30T10:00:00">Завтрак</Meal>
10+
<Meal calories="1000" dateTime="2023-01-30T13:00:00">Обед</Meal>
11+
<Meal calories="500" dateTime="2023-01-30T20:00:00">Ужин</Meal>
12+
<Meal calories="100" dateTime="2023-01-31T00:00:00">Еда на граничное значение</Meal>
13+
<Meal calories="500" dateTime="2023-01-31T10:00:00" foo="bar">Завтрак</Meal>
14+
<Meal calories="1000" dateTime="2023-01-30T13:00:00">Обед</Meal>
15+
<Meal calories="510" dateTime="2023-01-30T20:00:00">Ужин</Meal>
16+
</Meals>
17+
</User>
18+
<User email="admin@gmail.com" caloriesPerDay="1900" name="Admin"
19+
password="admin" registered="2023-01-01T13:00:00" roles="admin user">
20+
<Meals>
21+
<Meal calories="510" dateTime="2023-01-30T14:00:00">Админ ланч</Meal>
22+
<Meal calories="730" dateTime="2023-01-30T21:00:00">Админ ужин</Meal>
23+
</Meals>
24+
</User>
25+
<User enabled="false" email="guest@gmail.com" caloriesPerDay="2000" name="Guest"
26+
password="guest" registered="2023-01-01T13:00:00">
27+
</User>
28+
</Users>
29+
</UsersWithMeals>

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,19 @@
2727
<groupId>org.springframework.shell</groupId>
2828
<artifactId>spring-shell-starter</artifactId>
2929
</dependency>
30+
31+
<!-- Tests-->
3032
<dependency>
3133
<groupId>org.springframework.boot</groupId>
3234
<artifactId>spring-boot-starter-test</artifactId>
3335
<scope>test</scope>
3436
</dependency>
37+
<!-- https://youtrack.jetbrains.com/issue/IDEA-231927 -->
38+
<dependency>
39+
<groupId>org.junit.platform</groupId>
40+
<artifactId>junit-platform-launcher</artifactId>
41+
<scope>test</scope>
42+
</dependency>
3543
</dependencies>
3644

3745
<build>

src/main/java/ru/javaops/docjava/Commands.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
import org.springframework.shell.standard.ShellComponent;
44
import org.springframework.shell.standard.ShellMethod;
55
import org.springframework.shell.standard.ShellOption;
6+
import org.xml.sax.SAXException;
7+
import ru.javaops.docjava.xml.xsd.SchemaUtil;
68

79
import java.io.File;
10+
import java.io.IOException;
811
import java.util.List;
912

1013
@ShellComponent
1114
public class Commands {
1215
@ShellMethod(key = "xsd", value = "Validate XML file against XSD (XML Schema)")
1316
public void xsdValidate(@ShellOption(value = {"input", "-i"}, help = "Input file") File inputFile,
14-
@ShellOption(value = {"schema", "-s"}, help = "XSD schema file") File xsdSchema) {
15-
System.out.println("\nInput file: " + inputFile.getAbsolutePath());
16-
System.out.println("XSD schema file: " + xsdSchema.getAbsolutePath());
17+
@ShellOption(value = {"schema", "-s"}, help = "XSD schema file") File xsdSchema) throws IOException, SAXException {
18+
SchemaUtil.validate(inputFile, xsdSchema);
1719
}
1820

1921
@ShellMethod(key = "jaxb", value = "Process XML file via JAXB")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package ru.javaops.docjava.xml.xsd;
2+
3+
import org.xml.sax.SAXException;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.io.Reader;
8+
import java.nio.file.Files;
9+
10+
public class SchemaUtil {
11+
12+
public static void validate(File inputFile, File xsdSchema) throws IOException, SAXException {
13+
try (Reader reader = Files.newBufferedReader(inputFile.toPath())) {
14+
Schemas.validate(reader, Schemas.of(xsdSchema));
15+
}
16+
System.out.println(inputFile.getAbsolutePath() + " is valid");
17+
}
18+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package ru.javaops.docjava.xml.xsd;
2+
3+
import org.xml.sax.SAXException;
4+
5+
import javax.xml.XMLConstants;
6+
import javax.xml.transform.stream.StreamSource;
7+
import javax.xml.validation.Schema;
8+
import javax.xml.validation.SchemaFactory;
9+
import java.io.File;
10+
import java.io.IOException;
11+
import java.io.Reader;
12+
import java.io.StringReader;
13+
14+
public class Schemas {
15+
private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
16+
17+
// SchemaFactory is not thread-safe
18+
public static synchronized Schema of(File file) {
19+
try {
20+
return SCHEMA_FACTORY.newSchema(file);
21+
} catch (SAXException e) {
22+
throw new RuntimeException(e);
23+
}
24+
}
25+
26+
public static void validate(String str, Schema schema) throws IOException, SAXException {
27+
validate(new StringReader(str), schema);
28+
}
29+
30+
public static void validate(Reader reader, Schema schema) throws IOException, SAXException {
31+
schema.newValidator().validate(new StreamSource(reader));
32+
}
33+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package ru.javaops.docjava.xml.xsd;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.xml.sax.SAXException;
5+
import org.xml.sax.SAXParseException;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
10+
import static org.junit.jupiter.api.Assertions.assertThrows;
11+
12+
class SchemaUtilTest {
13+
private static final File xmlSchema = new File("in/usersWithMeals.xsd");
14+
15+
@Test
16+
void validateOK() throws IOException, SAXException {
17+
SchemaUtil.validate(new File("in/usersWithMeals.xml"), xmlSchema);
18+
}
19+
20+
@Test
21+
void testValidateNOK() throws IOException {
22+
assertThrows(SAXParseException.class,
23+
() -> SchemaUtil.validate(new File("in/badXmlFile.xml"), xmlSchema), "Except bad format exception");
24+
}
25+
}

0 commit comments

Comments
 (0)