diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc index df2e416dee9ce14353d1b5564b03e78e27c64ded..ae789fbbe45fbfd8375ca997857dfdfeb79378f7 100644 --- a/core/Universal_charstring.cc +++ b/core/Universal_charstring.cc @@ -1878,7 +1878,30 @@ int UNIVERSAL_CHARSTRING::XER_encode(const XERdescriptor_t& p_td, if (checker.NodeType() == XML_READER_TYPE_ELEMENT && (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT))) { const char* xmlns = (const char*)checker.NamespaceUri(); - check_namespace_restrictions(p_td, xmlns); + // If no xmlns attribute found, and only one namespace is allowed then + // append the xmlns attribute with the namespace. + if (xmlns == NULL && (p_td.xer_bits & ANY_FROM) && p_td.nof_ns_uris == 1 && + p_td.ns_uris[0] != NULL && strlen(p_td.ns_uris[0]) != 0) { + // Find the position of the '>' character + const char * pos = strchr((const char*)(other_buf.get_data()), '>'); + int index = (int)(pos - (const char*)other_buf.get_data()); + + // Create a new TTCN_Buffer which will contain the anyelement with + // the xmlns attribute. + TTCN_Buffer new_buf; + new_buf.put_s(index, other_buf.get_data()); + new_buf.put_s(8, (const unsigned char*)" xmlns='"); + size_t len = strlen(p_td.ns_uris[0]); + new_buf.put_s(len, (const unsigned char*)p_td.ns_uris[0]); + new_buf.put_c('\''); + + other_buf.set_pos(index); + len = strlen((const char*)other_buf.get_read_data()); + new_buf.put_s(len, other_buf.get_read_data()); + other_buf = new_buf; + } else { + check_namespace_restrictions(p_td, xmlns); + } } } diff --git a/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp b/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp index 31b4e355960bd1f6ac837fe7eb2848593c807095..6752ac5a6e3bfd96d491c0c92856a0157aa07d53 100644 --- a/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp @@ -351,6 +351,59 @@ testcase decode_only() runs on AE CHECK_DECODE(exer_dec_aaoa, estr_marx, anys_and_only_anys, marx_dec); } +/* * * * * * * * * * * * */ +// ANY-ELEMENT with only one allowed namespace. + +type record AEProductSingle { + charstring name, + integer price, + universal charstring info +} +with { + variant (info) "anyElement from 'http://www.example.com/A'" +} + +DECLARE_XER_ENCODERS(AEProductSingle, aes); +DECLARE_EXER_ENCODERS(AEProductSingle, aes); + +const AEProductSingle aesp := { + name := "Trousers", + price := 20, + info := "<color available=""true"">red</color>" +} + +const AEProductSingle aesp_e := { + name := "Trousers", + price := 20, + info := "<color xmlns=\"http://www.example.com/A\" available=\"true\">red</color>" +} + +const universal charstring str_aes_e := +"<AEProductSingle>\n" & +"\t<name>Trousers</name>\n" & +"\t<price>20</price>\n" & +"\t<color available=\"true\" xmlns='http://www.example.com/A'>red</color>\n" & +"</AEProductSingle>\n\n"; + +const universal charstring str_aes_b := +"<AEProductSingle>\n" & +"\t<name>Trousers</name>\n" & +"\t<price>20</price>\n" & +"\t<info><color available="true">red</color></info>\n" & +"</AEProductSingle>\n\n"; + +testcase encode_aes() runs on AE +{ + CHECK_METHOD(bxer_enc_aes, aesp, str_aes_b); + CHECK_METHOD(exer_enc_aes, aesp, str_aes_e); +} + +testcase decode_aes() runs on AE +{ + CHECK_DECODE(bxer_dec_aes, str_aes_b, AEProductSingle, aesp); + CHECK_DECODE(exer_dec_aes, str_aes_e, AEProductSingle, aesp_e); +} + control { execute(encode_ae()) @@ -367,6 +420,9 @@ control execute(encode_only()) execute(decode_only()) + + execute(encode_aes()) + execute(decode_aes()) } }