diff --git a/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/NetworkXml.java b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/NetworkXml.java index ad7bfbfcc6a..4f8f37c364c 100644 --- a/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/NetworkXml.java +++ b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/NetworkXml.java @@ -78,7 +78,8 @@ private static void validate(Source xml, List additionalSchemas) { try { factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - int length = IidmXmlVersion.values().length + (int) Arrays.stream(IidmXmlVersion.values()).filter(v -> v.supportEquipmentValidationLevel()).count(); + int length = IidmXmlVersion.values().length + (int) Arrays.stream(IidmXmlVersion.values()) + .filter(IidmXmlVersion::supportEquipmentValidationLevel).count(); Source[] sources = new Source[additionalSchemas.size() + length]; int i = 0; int j = 0; diff --git a/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/VoltageLevelXml.java b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/VoltageLevelXml.java index 8e392e1d309..28b742320a8 100644 --- a/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/VoltageLevelXml.java +++ b/iidm/iidm-xml-converter/src/main/java/com/powsybl/iidm/xml/VoltageLevelXml.java @@ -16,9 +16,13 @@ import org.slf4j.LoggerFactory; import javax.xml.stream.XMLStreamException; +import java.util.HashMap; import java.util.Map; import java.util.Set; +import static com.powsybl.iidm.xml.PropertiesXml.NAME; +import static com.powsybl.iidm.xml.PropertiesXml.VALUE; + /** * @author Geoffroy Jamgotchian */ @@ -33,6 +37,7 @@ class VoltageLevelXml extends AbstractSimpleIdentifiableXml nodes, NetworkXmlWriterContext context) { try { - context.getWriter().writeEmptyElement(context.getVersion().getNamespaceURI(context.isValid()), "bus"); + boolean writeProperties = context.getVersion().compareTo(IidmXmlVersion.V_1_11) >= 0 && bus.hasProperty(); + if (writeProperties) { + context.getWriter().writeStartElement(context.getVersion().getNamespaceURI(context.isValid()), "bus"); + } else { + context.getWriter().writeEmptyElement(context.getVersion().getNamespaceURI(context.isValid()), "bus"); + } XmlUtil.writeDouble("v", bus.getV(), context.getWriter()); XmlUtil.writeDouble("angle", bus.getAngle(), context.getWriter()); context.getWriter().writeAttribute("nodes", StringUtils.join(nodes.toArray(), ',')); + if (writeProperties) { + PropertiesXml.write(bus, context); + context.getWriter().writeEndElement(); + } } catch (XMLStreamException e) { throw new UncheckedXmlStreamException(e); } @@ -338,16 +352,26 @@ private void readNodeBreakerTopology(VoltageLevel vl, NetworkXmlReaderContext co break; default: - throw new IllegalStateException("Unexpected element: " + context.getReader().getLocalName()); + throw new IllegalStateException(UNEXPECTED_ELEMENT + context.getReader().getLocalName()); } }); } - private void readCalculatedBus(VoltageLevel vl, NetworkXmlReaderContext context) { + private void readCalculatedBus(VoltageLevel vl, NetworkXmlReaderContext context) throws XMLStreamException { IidmXmlUtil.assertMinimumVersion(ROOT_ELEMENT_NAME, BusXml.ROOT_ELEMENT_NAME, IidmXmlUtil.ErrorMessage.NOT_SUPPORTED, IidmXmlVersion.V_1_1, context); double v = XmlUtil.readOptionalDoubleAttribute(context.getReader(), "v"); double angle = XmlUtil.readOptionalDoubleAttribute(context.getReader(), "angle"); String nodesString = context.getReader().getAttributeValue(null, "nodes"); + Map properties = new HashMap<>(); + XmlUtil.readUntilEndElement(BusXml.ROOT_ELEMENT_NAME, context.getReader(), () -> { + if (context.getReader().getLocalName().equals(PropertiesXml.PROPERTY)) { + String name = context.getReader().getAttributeValue(null, NAME); + String value = context.getReader().getAttributeValue(null, VALUE); + properties.put(name, value); + } else { + throw new IllegalStateException(UNEXPECTED_ELEMENT + context.getReader().getLocalName()); + } + }); context.getEndTasks().add(() -> { for (String str : nodesString.split(",")) { int node = Integer.parseInt(str); @@ -356,6 +380,7 @@ private void readCalculatedBus(VoltageLevel vl, NetworkXmlReaderContext context) Bus b = terminal.getBusView().getBus(); if (b != null) { b.setV(v).setAngle(angle); + properties.forEach(b::setProperty); break; } } @@ -388,7 +413,7 @@ private void readBusBreakerTopology(VoltageLevel vl, NetworkXmlReaderContext con break; default: - throw new IllegalStateException("Unexpected element: " + context.getReader().getLocalName()); + throw new IllegalStateException(UNEXPECTED_ELEMENT + context.getReader().getLocalName()); } }); } diff --git a/iidm/iidm-xml-converter/src/main/resources/xsd/iidm_V1_11.xsd b/iidm/iidm-xml-converter/src/main/resources/xsd/iidm_V1_11.xsd index 7601d087425..e820faaaff9 100644 --- a/iidm/iidm-xml-converter/src/main/resources/xsd/iidm_V1_11.xsd +++ b/iidm/iidm-xml-converter/src/main/resources/xsd/iidm_V1_11.xsd @@ -150,6 +150,9 @@ + + + diff --git a/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/NodeBreakerPropertiesOnBusTest.java b/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/NodeBreakerPropertiesOnBusTest.java new file mode 100644 index 00000000000..63b52f6a726 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/java/com/powsybl/iidm/xml/NodeBreakerPropertiesOnBusTest.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2023, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.iidm.xml; + +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.FictitiousSwitchFactory; +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +/** + * @author Etienne Lesot + */ +class NodeBreakerPropertiesOnBusTest extends AbstractXmlConverterTest { + @Test + void testPropertiesOnBus() throws IOException { + Network network = FictitiousSwitchFactory.create(); + network.setCaseDate(DateTime.parse("2017-06-25T17:43:00.000+01:00")); + network.getVoltageLevel("C").getBusView().getBus("C_0").setProperty("key_test", "value_test"); + + // can export and reload a network in current and older XIIDM versions + for (IidmXmlVersion version : IidmXmlVersion.values()) { + roundTripXmlTest(network, + (n, p) -> NetworkXml.writeAndValidate(n, + new ExportOptions().setVersion(version.toString(".")), p), + NetworkXml::read, + getVersionedNetworkPath("nodebreaker-busproperties.xml", version)); + } + } +} diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_0/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_0/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..6d951dfbff6 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_0/nodebreaker-busproperties.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_1/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_1/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..d1c7301a931 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_1/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_10/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_10/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..ca1a0b23d15 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_10/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_11/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_11/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..e7a48f3c0e8 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_11/nodebreaker-busproperties.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_2/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_2/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..99612668f76 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_2/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_3/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_3/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..68696e90d80 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_3/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_4/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_4/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..b012bc437f7 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_4/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_5/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_5/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..3c594937318 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_5/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_6/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_6/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..255ea9f20ca --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_6/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_7/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_7/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..6f7e724a911 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_7/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_8/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_8/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..886abe2427d --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_8/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidm/iidm-xml-converter/src/test/resources/V1_9/nodebreaker-busproperties.xml b/iidm/iidm-xml-converter/src/test/resources/V1_9/nodebreaker-busproperties.xml new file mode 100644 index 00000000000..45b2e5f10c6 --- /dev/null +++ b/iidm/iidm-xml-converter/src/test/resources/V1_9/nodebreaker-busproperties.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +