Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b773d73
Initial plan
Copilot Nov 21, 2025
4028d4b
Add XML character escaping for enum values in XSLT transformation gen…
Copilot Nov 21, 2025
0bf3564
Fix escape order to prevent double-escaping
Copilot Nov 21, 2025
2eb30a0
Merge branch 'main' into copilot/fix-special-characters-escaping
Markus1812 Dec 1, 2025
c6576d2
Update src/zcl_aff_writer_xslt.clas.testclasses.abap
Markus1812 Dec 1, 2025
c4c077d
Merge branch 'main' into copilot/fix-special-characters-escaping
Markus1812 Dec 2, 2025
5fb3ed0
Add integration test for struc_with_special_char_enums
Copilot Dec 2, 2025
9fc7c57
Esc XML special characters in XSLT transformation
k4llist0 Jun 30, 2026
3245277
Revert "Esc XML special characters in XSLT transformation"
k4llist0 Jun 30, 2026
d7dfb21
Handle special characters
k4llist0 Jul 1, 2026
cf6b220
update npm dependencies (#337)
larshp Dec 12, 2025
e7ec8f5
Fix download and unit tests (#344)
wurzka Jan 12, 2026
852e78c
update npm dependencies (#345)
larshp Jan 15, 2026
4da8fc5
update npm dependencies (#347)
larshp Mar 4, 2026
ca4e07f
Bump fast-xml-parser from 5.4.2 to 5.5.6 (#348)
dependabot[bot] Mar 18, 2026
cc79e0e
Bump fast-xml-parser from 5.5.6 to 5.5.7 (#349)
dependabot[bot] Mar 20, 2026
fe3e841
fix datetime format (#353)
marcushoepfner Mar 30, 2026
6d5eafe
update npm dependencies (#357)
larshp Apr 2, 2026
4ebafc7
update npm dependencies (#358)
larshp Apr 8, 2026
3d7e650
update npm dependencies (#360)
larshp Apr 23, 2026
c670784
Bump @abaplint/transpiler-cli from 2.13.15 to 2.13.21 (#361)
dependabot[bot] May 7, 2026
c02311e
Bump @abaplint/runtime from 2.13.15 to 2.13.22 (#362)
dependabot[bot] May 7, 2026
0460c82
Bump @abaplint/cli from 2.119.2 to 2.119.14 (#363)
dependabot[bot] May 7, 2026
281ea52
chore(hyperspace): 🤖 Add PR Bot Configuration (#365)
hyperspace-pr-bot[bot] May 8, 2026
76c01fb
Update Permissions in Workflows (#364)
schneidermic0 May 8, 2026
90e5091
update npm dependencies (#373)
larshp Jun 25, 2026
a098d15
Bump @abaplint/transpiler-cli from 2.13.30 to 2.13.31 (#376)
dependabot[bot] Jul 2, 2026
52417ba
Remove Callback Handling (#372)
huber-nicolas Jul 2, 2026
2300139
Remove again
k4llist0 Jul 2, 2026
fcaff48
Fix minors
k4llist0 Jul 2, 2026
02847b9
Merge branch 'main' into copilot/fix-special-characters-escaping
wurzka Jul 2, 2026
e37750b
Update src/zcl_aff_writer_xslt.clas.testclasses.abap
wurzka Jul 2, 2026
095639a
Escape special characters
k4llist0 Jul 2, 2026
f33897d
Fix abaplint
k4llist0 Jul 2, 2026
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
23 changes: 23 additions & 0 deletions src/zcl_aff_test_types.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,29 @@ CLASS zcl_aff_test_types DEFINITION
enum_component TYPE c LENGTH 2,
END OF struc_with_own_enum_values.

CONSTANTS:
BEGIN OF co_enum_special_chars,
"! <p class="shorttext">Less Than</p>
"! Less than
less_than TYPE c LENGTH 1 VALUE '<',
"! <p class="shorttext">Greater Than</p>
"! Greater than
greater_than TYPE c LENGTH 1 VALUE '>',
"! <p class="shorttext">Ampersand</p>
"! Ampersand
ampersand TYPE c LENGTH 1 VALUE '&',
END OF co_enum_special_chars.

TYPES:
"! <p class="shorttext">Structure With Special Character Enum Values</p>
"! Structure with special character enum values
BEGIN OF struc_with_special_char_enums,
"! <p class="shorttext">Enum With Special Characters</p>
"! Enum with special characters
"! $values {@link zcl_aff_test_types.data:co_enum_special_chars }
special_char_enum TYPE c LENGTH 1,
END OF struc_with_special_char_enums.

CLASS-DATA subschema TYPE string_table.

CLASS-DATA expected_var TYPE REF TO data.
Expand Down
24 changes: 21 additions & 3 deletions src/zcl_aff_writer_xslt.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,12 @@ CLASS zcl_aff_writer_xslt DEFINITION
get_to_ref
IMPORTING
name TYPE string
RETURNING VALUE(result) TYPE string.
RETURNING VALUE(result) TYPE string,
escape_xml_chars
IMPORTING
value TYPE string
RETURNING
VALUE(result) TYPE string.


ENDCLASS.
Expand Down Expand Up @@ -459,16 +464,19 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION.

METHOD get_abap_value.
DATA abap_value_copy TYPE string.
DATA escaped_value TYPE string.
CASE element_description->type_kind.
WHEN cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 OR
cl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_int8.
abap_value_copy = abap_value.
CONDENSE abap_value_copy.
result = |I({ abap_value_copy })|.
WHEN cl_abap_typedescr=>typekind_num.
result = |N('{ abap_value }')|.
escaped_value = escape_xml_chars( abap_value ).
result = |N('{ escaped_value }')|.
WHEN OTHERS.
result = |'{ abap_value }'|.
escaped_value = escape_xml_chars( abap_value ).
result = |'{ escaped_value }'|.
ENDCASE.
ENDMETHOD.

Expand Down Expand Up @@ -811,4 +819,14 @@ CLASS zcl_aff_writer_xslt IMPLEMENTATION.
ENDLOOP.
ENDMETHOD.

METHOD escape_xml_chars.
result = value.
" Ampersand must be replaced first to avoid double-escaping
REPLACE ALL OCCURRENCES OF '&' IN result WITH '&#38;'.
REPLACE ALL OCCURRENCES OF '<' IN result WITH '&#60;'.
REPLACE ALL OCCURRENCES OF '>' IN result WITH '&#62;'.
REPLACE ALL OCCURRENCES OF '"' IN result WITH '&#34;'.
REPLACE ALL OCCURRENCES OF '''' IN result WITH '&#39;'.
ENDMETHOD.

Comment on lines +740 to +748

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use ABAP's built-in function escape to escape xml?

See https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENESCAPE_FUNCTIONS.html

ENDCLASS.
70 changes: 70 additions & 0 deletions src/zcl_aff_writer_xslt.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,7 @@ CLASS ltcl_type_writer_xslt_ad DEFINITION FINAL FOR TESTING
structure_with_enums FOR TESTING RAISING cx_static_check,
structure_with_default_problem FOR TESTING RAISING cx_static_check,
struc_with_own_enum_values FOR TESTING RAISING cx_static_check,
struc_with_special_char_enums FOR TESTING RAISING cx_static_check,
enable_extension FOR TESTING RAISING cx_static_check.
ENDCLASS.

Expand Down Expand Up @@ -2566,6 +2567,39 @@ CLASS ltcl_type_writer_xslt_ad IMPLEMENTATION.
validate_output( act_output ).
ENDMETHOD.

METHOD struc_with_special_char_enums.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration test in ltcl_integration_test_ad missing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration test in ltcl_integration_test_ad missing

@copilot

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added integration test struc_with_special_char_enums in ltcl_integration_test_ad that tests round-trip serialization/deserialization for all three special characters (<, >, &). Commit: 5fb3ed0

DATA test_type TYPE zcl_aff_test_types=>struc_with_special_char_enums.
DATA(act_output) = test_generator->generate_type( test_type ).
me->exp_transformation = VALUE #(
( `<tt:cond>` )
( ` <object>` )
( ` <tt:group>` )
( ` <tt:cond s-check="not-initial(SPECIAL_CHAR_ENUM)" frq="?">` )
( ` <str name="specialCharEnum">` )
( ` <tt:value ref="SPECIAL_CHAR_ENUM" map="` )
( ` val('&#60;')=xml('lessThan'),` )
( ` val('&#62;')=xml('greaterThan'),` )
( ` val('&#38;')=xml('ampersand')"` )
( ` />` )
( ` </str>` )
( ` </tt:cond>` )
( ` <tt:d-cond frq="*">` )
( ` <_ tt:lax="on">` )
( ` <tt:call-method class="CL_AFF_XSLT_CALLBACK_TYPE" name="RAISE_DIFFERENT_TYPE_EXCEPTION" reader="IO_READER">` )
( ` <tt:with-parameter name="MEMBERS" val="'specialCharEnum;'"/>` )
( ` </tt:call-method>` )
( ` <tt:skip/>` )
( ` </_>` )
( ` </tt:d-cond>` )
( ` <tt:d-cond frq="?">` )
( ` <__/>` )
( ` </tt:d-cond>` )
( ` </tt:group>` )
( ` </object>` )
( `</tt:cond>` ) ).
validate_output( act_output ).
ENDMETHOD.

METHOD validate_output.
DATA exp TYPE string_table.

Expand Down Expand Up @@ -2653,6 +2687,8 @@ RISK LEVEL DANGEROUS.

struc_with_own_enum_values FOR TESTING RAISING cx_static_check,

struc_with_special_char_enums FOR TESTING RAISING cx_static_check,

from_abap_to_json
IMPORTING
test_type TYPE data
Expand Down Expand Up @@ -3224,6 +3260,40 @@ CLASS ltcl_integration_test_ad IMPLEMENTATION.
act_data = test_type ).
ENDMETHOD.

METHOD struc_with_special_char_enums.
DATA test_type TYPE zcl_aff_test_types=>struc_with_special_char_enums.
test_type = VALUE #( special_char_enum = '<' ).
exp_json = VALUE #(
( `{` )
( ` "specialCharEnum": "lessThan"` )
( `}` ) ).
do_integration_test(
EXPORTING
test_type = test_type
CHANGING
act_data = test_type ).
test_type = VALUE #( special_char_enum = '>' ).
exp_json = VALUE #(
( `{` )
( ` "specialCharEnum": "greaterThan"` )
( `}` ) ).
do_integration_test(
EXPORTING
test_type = test_type
CHANGING
act_data = test_type ).
test_type = VALUE #( special_char_enum = '&' ).
exp_json = VALUE #(
( `{` )
( ` "specialCharEnum": "ampersand"` )
( `}` ) ).
do_integration_test(
EXPORTING
test_type = test_type
CHANGING
act_data = test_type ).
ENDMETHOD.

METHOD do_integration_test.
from_abap_to_json(
EXPORTING
Expand Down
Loading