Skip to content

Commit eaf96bc

Browse files
author
Dennis Labordus
authored
Merge pull request #129 from com-pas/validate-compas-xml
Added Compas XSD to XSD validator to validate Compas Elements.
2 parents 86a5989 + 1c55373 commit eaf96bc

File tree

3 files changed

+139
-2
lines changed

3 files changed

+139
-2
lines changed

validator/src/main/java/org/lfenergy/compas/scl/validator/xsd/XSDValidator.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.xml.sax.SAXException;
1313

1414
import javax.xml.XMLConstants;
15+
import javax.xml.transform.Source;
1516
import javax.xml.transform.sax.SAXSource;
1617
import javax.xml.transform.stream.StreamSource;
1718
import javax.xml.validation.SchemaFactory;
@@ -35,10 +36,12 @@ public XSDValidator(List<ValidationError> errorList, String sclData) {
3536
var sclVersion = info.getSclVersion();
3637

3738
try {
39+
var sclXsd = new StreamSource(getClass().getClassLoader().getResourceAsStream("xsd/SCL" + sclVersion + "/SCL.xsd"));
40+
var compasXsd = new StreamSource(getClass().getClassLoader().getResourceAsStream("xsd/SCL_CoMPAS.xsd"));
41+
3842
var factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
3943
factory.setResourceResolver(new ResourceResolver(sclVersion));
40-
var schema = factory.newSchema(
41-
new StreamSource(getClass().getClassLoader().getResourceAsStream("xsd/SCL" + sclVersion + "/SCL.xsd")));
44+
var schema = factory.newSchema(new Source[]{sclXsd, compasXsd});
4245
validator = schema.newValidator();
4346
validator.setErrorHandler(new XSDErrorHandler(errorList));
4447
} catch (SAXException exception) {

validator/src/test/java/org/lfenergy/compas/scl/validator/xsd/XSDValidatorTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,32 @@ void validate_WhenCalledWithSclDataWithXsdValidationErrors_ThenErrorsAreRetrieve
4646
}
4747
}
4848

49+
@Test
50+
void validate_WhenCalledWithSclDataWithCompasXsdValidationErrors_ThenErrorsAreRetrieved() throws IOException {
51+
var errorList = new ArrayList<ValidationError>();
52+
try (var inputStream = getClass()
53+
.getResourceAsStream("/scl/validation/example-with-compas-validation-errors.scd")) {
54+
var data = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
55+
new XSDValidator(errorList, data).validate();
56+
57+
assertEquals(4, errorList.size());
58+
59+
var error = errorList.get(0);
60+
assertEquals("Value 'INVALID' is not facet-valid with respect to enumeration '[SSD, IID, ICD, SCD, CID, " +
61+
"SED, ISD, STD]'. It must be a value from the enumeration.", error.getMessage());
62+
assertEquals("XSD/cvc-enumeration-valid", error.getRuleName());
63+
assertEquals(10, error.getLineNumber());
64+
assertEquals(57, error.getColumnNumber());
65+
66+
error = errorList.get(2);
67+
assertEquals("Value 'Invalid Label' is not facet-valid with respect to pattern '[A-Za-z][0-9A-Za-z_-]*' " +
68+
"for type 'tCompasLabel'.", error.getMessage());
69+
assertEquals("XSD/cvc-pattern-valid", error.getRuleName());
70+
assertEquals(12, error.getLineNumber());
71+
assertEquals(55, error.getColumnNumber());
72+
}
73+
}
74+
4975
@Test
5076
void validate_WhenCalledWithSclDataContainingInvalidVersion_ThenExceptionIsThrown() throws IOException {
5177
var errorList = new ArrayList<ValidationError>();
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- SPDX-FileCopyrightText: 2020 RTE FRANCE -->
3+
<!-- -->
4+
<!-- SPDX-License-Identifier: Apache-2.0 -->
5+
6+
<SCL xmlns="http://www.iec.ch/61850/2003/SCL" xmlns:compas="https://www.lfenergy.org/compas/extension/v1"
7+
version="2007" revision="B" release="4">
8+
<Private type="compas_scl">
9+
<compas:SclName>MiniGrid</compas:SclName>
10+
<compas:SclFileType>INVALID</compas:SclFileType>
11+
<compas:Labels>
12+
<compas:Label>Invalid Label</compas:Label>
13+
</compas:Labels>
14+
</Private>
15+
<Header id="f9283708-bf4f-412c-a1d6-f947b9ac3000" version="1.0.0" revision="Revision" toolID="toolID"
16+
nameStructure="IEDName"/>
17+
<IED name="IED_NAME">
18+
<AccessPoint name="AP_NAME">
19+
<Server>
20+
<Authentication/>
21+
<LDevice inst="LDPO">
22+
<LN0 lnType="LN2" lnClass="LLN0" inst="">
23+
<Inputs>
24+
<ExtRef intAddr="INTADDR" pDO="DO1" desc="DESC1"/>
25+
<ExtRef intAddr="INTADDR" pDO="DO2" desc="DESC2"/>
26+
</Inputs>
27+
</LN0>
28+
<LN lnType="LN1" lnClass="PIOC" inst="1">
29+
<Inputs>
30+
<ExtRef intAddr="INTADDR" pDO="DO1" desc="DESC1"/>
31+
<ExtRef intAddr="INTADDR" pDO="DO2" desc="DESC2"/>
32+
</Inputs>
33+
</LN>
34+
<LN lnType="LN1" lnClass="PIOC" inst="2">
35+
<Inputs>
36+
<ExtRef intAddr="INTADDR" pDO="DO1" desc="DESC1"/>
37+
<ExtRef intAddr="INTADDR" pDO="DO2" desc="DESC2"/>
38+
</Inputs>
39+
</LN>
40+
</LDevice>
41+
</Server>
42+
</AccessPoint>
43+
</IED>
44+
<DataTypeTemplates>
45+
<LNodeType lnClass="LLN0" id="LN2">
46+
<DO name="Beh" type="DO1" transient="false"/>
47+
<DO name="FACntRs" type="DO2" transient="true"/>
48+
<DO name="StrVal" type="DO3" transient="false"/>
49+
</LNodeType>
50+
<LNodeType lnClass="PIOC" id="LN1">
51+
<DO name="Beh" type="DO1" transient="false"/>
52+
<DO name="FACntRs" type="DO2" transient="true"/>
53+
<DO name="StrVal" type="DO3" transient="false"/>
54+
</LNodeType>
55+
<DOType cdc="WYE" id="DO1">
56+
<DA fc="DC" dchg="false" qchg="false" dupd="false" name="dataNs" bType="VisString255">
57+
<Val>IEC 61850-7-3:2007B</Val>
58+
</DA>
59+
<DA fc="CF" dchg="true" qchg="false" dupd="false" name="smpRate" bType="INT32U"/>
60+
</DOType>
61+
<DOType cdc="WYE" id="DO2">
62+
<SDO name="phsBHar" type="DO4"/>
63+
<DA fc="CF" dchg="true" qchg="false" dupd="true" name="angRef" bType="Enum" type="PhaseAngleReferenceKind"/>
64+
</DOType>
65+
<DOType cdc="WYE" id="DO3">
66+
<SDO name="neutHar" type="DO4"/>
67+
<DA fc="CF" dchg="true" qchg="false" dupd="false" name="smpRate" bType="INT32U"/>
68+
<DA fc="ST" dchg="false" qchg="false" dupd="false" name="origin" bType="Struct" type="DA3"/>
69+
</DOType>
70+
<DOType cdc="WYE" id="DO4">
71+
<DA fc="DC" dchg="false" qchg="false" dupd="false" name="configRev" bType="VisString255" valKind="RO"
72+
valImport="false"/>
73+
</DOType>
74+
<DAType id="DA1">
75+
<BDA name="operTm" bType="Timestamp"/>
76+
<BDA name="origin" bType="Struct" type="DA3"/>
77+
<ProtNs type="8-MMS">IEC 61850-8-1:2003</ProtNs>
78+
</DAType>
79+
<DAType id="DA2">
80+
<BDA name="T" bType="Timestamp"/>
81+
<BDA name="ctlVal" bType="Enum" type="RecCycModKind"/>
82+
<ProtNs type="8-MMS">IEC 61850-8-1:2003</ProtNs>
83+
</DAType>
84+
<DAType id="DA3">
85+
<BDA name="Check" bType="Check"/>
86+
<BDA name="Test" bType="BOOLEAN"/>
87+
<ProtNs type="8-MMS">IEC 61850-8-1:2003</ProtNs>
88+
</DAType>
89+
<EnumType id="RecCycModKind">
90+
<EnumVal ord="1">Completed</EnumVal>
91+
<EnumVal ord="2">Cancelled</EnumVal>
92+
<EnumVal ord="3">New adjustments</EnumVal>
93+
<EnumVal ord="4">AnotherValue</EnumVal>
94+
</EnumType>
95+
<EnumType id="PhaseAngleReferenceKind">
96+
<EnumVal ord="0">Va</EnumVal>
97+
<EnumVal ord="1">Vb</EnumVal>
98+
<EnumVal ord="2">Vc</EnumVal>
99+
<EnumVal ord="3">Aa</EnumVal>
100+
<EnumVal ord="4">Ab</EnumVal>
101+
<EnumVal ord="5">Ac</EnumVal>
102+
<EnumVal ord="6">Vab</EnumVal>
103+
<EnumVal ord="7">Vbc</EnumVal>
104+
<EnumVal ord="8">Vca</EnumVal>
105+
<EnumVal ord="9">AnotherValue</EnumVal>
106+
</EnumType>
107+
</DataTypeTemplates>
108+
</SCL>

0 commit comments

Comments
 (0)