Skip to content

Commit 5f78a71

Browse files
committed
Add more options
- Accept CSV data with quotes. - Enable XML output indentation.
1 parent bc71ec7 commit 5f78a71

File tree

2 files changed

+105
-19
lines changed

2 files changed

+105
-19
lines changed

src/index.test.ts

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ it('converts basic CSV to XML', () => {
88
const xml = csvToXml(csv);
99
expect(xml).toBe(
1010
`<row>
11-
<color>"red"</color>
12-
<maxSpeed>120</maxSpeed>
13-
<age>2</age>
11+
<color>"red"</color>
12+
<maxSpeed>120</maxSpeed>
13+
<age>2</age>
1414
</row>
1515
<row>
16-
<color>"blue"</color>
17-
<maxSpeed>150</maxSpeed>
18-
<age>4</age>
16+
<color>"blue"</color>
17+
<maxSpeed>150</maxSpeed>
18+
<age>4</age>
1919
</row>
2020
`
2121
);
@@ -28,9 +28,9 @@ it('accepts custom separator', () => {
2828
const xml = csvToXml(csv, { separator: '|' });
2929
expect(xml).toBe(
3030
`<row>
31-
<color>"red"</color>
32-
<maxSpeed>120</maxSpeed>
33-
<age>2</age>
31+
<color>"red"</color>
32+
<maxSpeed>120</maxSpeed>
33+
<age>2</age>
3434
</row>
3535
`
3636
);
@@ -43,9 +43,9 @@ it('accepts custom rowName', () => {
4343
const xml = csvToXml(csv, { rowName: 'car' });
4444
expect(xml).toBe(
4545
`<car>
46-
<color>"red"</color>
47-
<maxSpeed>120</maxSpeed>
48-
<age>2</age>
46+
<color>"red"</color>
47+
<maxSpeed>120</maxSpeed>
48+
<age>2</age>
4949
</car>
5050
`
5151
);
@@ -58,9 +58,9 @@ it('accepts custom headerList', () => {
5858
const xml = csvToXml(csv, { headerList: ['color', 'maxSpeed', 'age'] });
5959
expect(xml).toBe(
6060
`<row>
61-
<color>"red"</color>
62-
<maxSpeed>120</maxSpeed>
63-
<age>2</age>
61+
<color>"red"</color>
62+
<maxSpeed>120</maxSpeed>
63+
<age>2</age>
6464
</row>
6565
`
6666
);
@@ -72,9 +72,9 @@ it('accepts CSV with no headers', () => {
7272
const xml = csvToXml(csv, { header: false });
7373
expect(xml).toBe(
7474
`<row>
75-
<col1>"red"</col1>
76-
<col2>120</col2>
77-
<col3>2</col3>
75+
<col1>"red"</col1>
76+
<col2>120</col2>
77+
<col3>2</col3>
7878
</row>
7979
`
8080
);
@@ -85,12 +85,81 @@ it('accepts custom EOL', () => {
8585
"red",120,2`;
8686

8787
const xml = csvToXml(csv, { eol: '\r\n' });
88+
expect(xml).toBe(
89+
`<row>
90+
<color>"red"</color>
91+
<maxSpeed>120</maxSpeed>
92+
<age>2</age>
93+
</row>
94+
`
95+
);
96+
});
97+
98+
it('accepts custom indentation', () => {
99+
const csv = `color,maxSpeed,age
100+
"red",120,2`;
101+
102+
const xml = csvToXml(csv, { indentation: 0 });
88103
expect(xml).toBe(
89104
`<row>
90105
<color>"red"</color>
91106
<maxSpeed>120</maxSpeed>
92107
<age>2</age>
93108
</row>
109+
`
110+
);
111+
112+
const xml2 = csvToXml(csv, { indentation: 2 });
113+
expect(xml2).toBe(
114+
`<row>
115+
<color>"red"</color>
116+
<maxSpeed>120</maxSpeed>
117+
<age>2</age>
118+
</row>
119+
`
120+
);
121+
122+
const xml3 = csvToXml(csv, { indentation: ' ' });
123+
expect(xml3).toBe(
124+
`<row>
125+
<color>"red"</color>
126+
<maxSpeed>120</maxSpeed>
127+
<age>2</age>
128+
</row>
129+
`
130+
);
131+
});
132+
133+
it('accepts CSV with quotes', () => {
134+
const csv = `color,maxSpeed,age
135+
"red",'120',2`;
136+
const xml = csvToXml(csv, { quotes: 'double' });
137+
expect(xml).toBe(
138+
`<row>
139+
<color>red</color>
140+
<maxSpeed>'120'</maxSpeed>
141+
<age>2</age>
142+
</row>
143+
`
144+
);
145+
146+
const xml2 = csvToXml(csv, { quotes: 'single' });
147+
expect(xml2).toBe(
148+
`<row>
149+
<color>"red"</color>
150+
<maxSpeed>120</maxSpeed>
151+
<age>2</age>
152+
</row>
153+
`
154+
);
155+
156+
const xml3 = csvToXml(csv, { quotes: 'none' });
157+
expect(xml3).toBe(
158+
`<row>
159+
<color>"red"</color>
160+
<maxSpeed>'120'</maxSpeed>
161+
<age>2</age>
162+
</row>
94163
`
95164
);
96165
});

src/index.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ type CSVToXMLOptions = {
66
rowName?: string;
77
headerList?: string[];
88
header?: boolean;
9+
indentation?: number | string;
10+
quotes?: 'single' | 'double' | 'none';
911
};
1012

1113
const defaultOptions: CSVToXMLOptions = {
@@ -14,6 +16,8 @@ const defaultOptions: CSVToXMLOptions = {
1416
rowName: 'row',
1517
header: true,
1618
headerList: [],
19+
indentation: 4,
20+
quotes: 'none',
1721
};
1822

1923
export default function csvToXml(
@@ -59,6 +63,11 @@ export default function csvToXml(
5963
return xml;
6064
}
6165

66+
const spaces =
67+
typeof usedOptions.indentation === 'number'
68+
? ' '.repeat(usedOptions.indentation)
69+
: usedOptions.indentation;
70+
6271
for (let i = rowStartLine; i < csvData.length; i++) {
6372
const details = csvData[i].split(separator);
6473

@@ -69,7 +78,15 @@ export default function csvToXml(
6978

7079
xml += `<${usedOptions.rowName}>\n`;
7180
for (let j = 0; j < colCount; j++) {
72-
xml += `<${usedHeaders[j]}>${details[j]}</${usedHeaders[j]}>\n`;
81+
let colValue = details[j];
82+
if (!usedOptions.quotes || usedOptions.quotes !== 'none') {
83+
const quoteRemovingRegex = {
84+
double: /"(.*?)"/,
85+
single: /'(.*?)'/,
86+
}[usedOptions.quotes!];
87+
colValue = colValue.replace(quoteRemovingRegex, '$1');
88+
}
89+
xml += `${spaces}<${usedHeaders[j]}>${colValue}</${usedHeaders[j]}>\n`;
7390
}
7491
xml += `</${usedOptions.rowName}>\n`;
7592
}

0 commit comments

Comments
 (0)