Skip to content

Commit 210491e

Browse files
committed
fix: regression in attrib + test
Signed-off-by: Tuan Anh Tran <me@tuananh.org>
1 parent 47af163 commit 210491e

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

dist/camaro.wasm

346 Bytes
Binary file not shown.

src/camaro.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ static pugi::xml_node follow_path(pugi::xml_node ctx, const char *path,
126126

127127
static string follow_path_string(pugi::xml_node ctx, const string &path,
128128
bool absolute) {
129+
// Bare @attr selects an attribute on the context node.
130+
if (!path.empty() && path[0] == '@') {
131+
if (!ctx)
132+
return "";
133+
pugi::xml_attribute a = ctx.attribute(path.c_str() + 1);
134+
return a ? string(a.value()) : "";
135+
}
129136
const size_t at_pos = path.rfind("/@");
130137
if (at_pos != string::npos) {
131138
const string elem = path.substr(0, at_pos);
@@ -142,6 +149,13 @@ static string follow_path_string(pugi::xml_node ctx, const string &path,
142149

143150
static double follow_path_number(pugi::xml_node ctx, const string &path,
144151
bool absolute) {
152+
// Bare @attr selects an attribute on the context node.
153+
if (!path.empty() && path[0] == '@') {
154+
if (!ctx)
155+
return std::nan("");
156+
pugi::xml_attribute a = ctx.attribute(path.c_str() + 1);
157+
return a ? a.as_double() : std::nan("");
158+
}
145159
const size_t at_pos = path.rfind("/@");
146160
if (at_pos != string::npos) {
147161
const string elem = path.substr(0, at_pos);

test/context-attribute.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const t = require('tape')
2+
const { transform } = require('../')
3+
4+
t.test('bare @attr on context node (README example)', async (t) => {
5+
const xml = `
6+
<players>
7+
<player jerseyNumber="10">
8+
<name>wayne rooney</name>
9+
<isRetired>false</isRetired>
10+
<yearOfBirth>1985</yearOfBirth>
11+
</player>
12+
<player jerseyNumber="7">
13+
<name>cristiano ronaldo</name>
14+
<isRetired>false</isRetired>
15+
<yearOfBirth>1985</yearOfBirth>
16+
</player>
17+
</players>
18+
`
19+
const template = ['players/player', {
20+
name: 'title-case(name)',
21+
jerseyNumber: '@jerseyNumber',
22+
yearOfBirth: 'number(yearOfBirth)',
23+
jerseyAsNumber: 'number(@jerseyNumber)',
24+
isRetired: 'boolean(isRetired = "true")'
25+
}]
26+
27+
const result = await transform(xml, template)
28+
t.equal(result.length, 2)
29+
t.equal(result[0].jerseyNumber, '10')
30+
t.equal(result[0].jerseyAsNumber, 10)
31+
t.equal(result[0].name, 'Wayne Rooney')
32+
t.equal(result[0].yearOfBirth, 1985)
33+
t.equal(result[0].isRetired, false)
34+
t.equal(result[1].jerseyNumber, '7')
35+
t.equal(result[1].jerseyAsNumber, 7)
36+
t.equal(result[1].isRetired, false)
37+
t.end()
38+
})

0 commit comments

Comments
 (0)