Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions include/rexsapi/XMLModelLoader.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,15 @@ namespace rexsapi
components = postProcessor.release();

TRelations relations;
std::set<std::string, std::less<>> usedRelations;
for (const auto& relation : doc.select_nodes("/model/relations/relation")) {
std::string relationId = detail::getStringAttribute(relation, "id");
try {
if (!usedRelations.emplace(relationId).second) {
result.addError(
TError{m_Mode.adapt(TErrorLevel::ERR), fmt::format("duplicate relation found for relation id={}", relationId)});
}

auto relationType = relationTypeFromString(detail::getStringAttribute(relation, "type"));
std::optional<uint32_t> order;
if (const auto orderAtt = relation.node().attribute("order"); !orderAtt.empty()) {
Expand All @@ -159,8 +165,7 @@ namespace rexsapi
}

TRelationReferences references;
for (const auto& reference :
doc.select_nodes(fmt::format("/model/relations/relation[@id = '{}']/ref", relationId).c_str())) {
for (const auto& reference : relation.node().children("ref")) {
std::string referenceId = detail::getStringAttribute(reference, "id");
try {
auto role = relationRoleFromString(detail::getStringAttribute(reference, "role"));
Expand Down
33 changes: 33 additions & 0 deletions test/XMLModelLoaderTest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,39 @@ TEST_CASE("XML model loader test")
CHECK(model);
}

SUBCASE("Load duplicate relation ids")
{
const std::string buffer = R"(
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<model applicationId="REXSApi Unit Test" applicationVersion="1.0" date="2022-05-05T10:35:00+02:00" version="1.4">
<relations>
<relation id="1" type="assembly">
<ref hint="gear_unit" id="1" role="assembly"/>
<ref hint="gear_casing" id="2" role="part"/>
</relation>
<relation id="1" type="assembly">
<ref hint="gear_unit" id="1" role="assembly"/>
<ref hint="external_load" id="3" role="part"/>
</relation>
</relations>
<components>
<component id="1" type="gear_unit" />
<component id="2" type="gear_casing" />
<component id="3" type="external_load" />
</components>
</model>
)";

rexsapi::detail::TBufferModelLoader<rexsapi::TXSDSchemaValidator, rexsapi::TXMLModelLoader> loader{validator,
buffer};
const auto model = loader.load(rexsapi::TMode::STRICT_MODE, result, registry);
CHECK_FALSE(result);
CHECK_FALSE(result.isCritical());
REQUIRE(model);
REQUIRE(result.getErrors().size() == 1);
CHECK(result.getErrors()[0].getMessage() == "duplicate relation found for relation id=1");
}

SUBCASE("Load invalid reference type")
{
const std::string buffer = R"(
Expand Down
Loading