diff --git a/t/xmlrpc.t b/t/xmlrpc.t
index c01d04b9e..45cbb400f 100644
--- a/t/xmlrpc.t
+++ b/t/xmlrpc.t
@@ -228,6 +228,14 @@ subtest 'parse_xml_value' => sub {
'1x'));
is(ref($a), 'ARRAY', 'array -> arrayref');
is_deeply($a, [1, 'x'], 'array elements parsed in order');
+
+ # Scalar tags must retain their type when a nested value is later encoded.
+ require JSON::PP;
+ my $typed = parse_xml_value(value_tree(
+ 'integer1800boolean1double2.5string1800'));
+ is(JSON::PP->new->canonical->encode($typed),
+ '{"boolean":1,"double":2.5,"integer":1800,"string":"1800"}',
+ 'nested scalar types preserved for JSON');
};
# Round-trip: encode_xml_value then parse_xml_value should reproduce the
diff --git a/xmlrpc-lib.pl b/xmlrpc-lib.pl
index 8a7fdb69a..d0d5f0edd 100644
--- a/xmlrpc-lib.pl
+++ b/xmlrpc-lib.pl
@@ -18,13 +18,14 @@ my ($base64) = &find_xmls("base64", $value, 1);
my ($struct) = &find_xmls("struct", $value, 1);
my ($array) = &find_xmls("array", $value, 1);
if ($scalar) {
- my ($type, $content) = ($scalar->[0], $scalar->[1]->[2] // "");
+ my ($type, $content) = ($scalar->[0], $scalar->[1]->[2] // "");
+ $type = lc($type);
- return int($content) if ($type eq "int" || $type eq "i4");
- return $content ? 1 : 0 if ($type eq "boolean");
- return $content + 0.0 if ($type eq "double");
+ return int($content) if ($type eq "int" || $type eq "i4");
+ return $content ? 1 : 0 if ($type eq "boolean");
+ return $content + 0.0 if ($type eq "double");
- return $content;
+ return $content;
}
elsif ($date) {
# Need to decode date