Skip to content

Commit 0adf991

Browse files
authored
Merge pull request #442 from Sushanth012/fix/xml-beautifier-attributes
fix(xml): preserve attributes when beautifying XML
2 parents 89a50e3 + 0168e7d commit 0adf991

5 files changed

Lines changed: 54 additions & 20 deletions

File tree

‎public/locales/en/xml.json‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
"resultTitle": "Beautified XML",
77
"shortDescription": "Format and beautify XML code",
88
"title": "XML Beautifier",
9+
"options": {
10+
"title": "Options",
11+
"preserveAttributesTitle": "Preserve Attributes",
12+
"preserveAttributesDesc": "Preserve the original XML attribute formatting and order."
13+
},
914
"toolInfo": {
1015
"description": "This tool allows you to format XML data with proper indentation and spacing, making it more readable and easier to work with.",
1116
"title": "XML Beautifier"

‎src/pages/tools/xml/xml-beautifier/index.tsx‎

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,53 @@ import { ToolComponentProps } from '@tools/defineTool';
44
import ToolTextInput from '@components/input/ToolTextInput';
55
import ToolTextResult from '@components/result/ToolTextResult';
66
import { CardExampleType } from '@components/examples/ToolExamples';
7+
import { GetGroupsType } from '@components/options/ToolOptions';
8+
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
79
import { beautifyXml } from './service';
810
import { InitialValuesType } from './types';
911
import { useTranslation } from 'react-i18next';
1012

11-
const initialValues: InitialValuesType = {};
13+
const initialValues: InitialValuesType = {
14+
preserveAttributes: true
15+
};
1216

1317
const exampleCards: CardExampleType<InitialValuesType>[] = [
1418
{
1519
title: 'Beautify XML',
1620
description: 'Beautify a compact XML string for readability.',
1721
sampleText: '<root><item>1</item><item>2</item></root>',
1822
sampleResult: `<root>\n <item>1</item>\n <item>2</item>\n</root>`,
19-
sampleOptions: {}
23+
sampleOptions: { preserveAttributes: true }
2024
}
2125
];
2226

23-
export default function XmlBeautifier({
24-
title,
25-
longDescription
26-
}: ToolComponentProps) {
27+
export default function XmlBeautifier({ title }: ToolComponentProps) {
2728
const { t } = useTranslation('xml');
2829
const [input, setInput] = useState<string>('');
2930
const [result, setResult] = useState<string>('');
3031

31-
const compute = (_values: InitialValuesType, input: string) => {
32-
setResult(beautifyXml(input, {}));
32+
const compute = (values: InitialValuesType, input: string) => {
33+
if (!input || input.trim() == '') return;
34+
setResult(beautifyXml(input, values));
3335
};
3436

37+
const getGroups: GetGroupsType<InitialValuesType> | null = ({
38+
values,
39+
updateField
40+
}) => [
41+
{
42+
title: t('xmlBeautifier.options.title'),
43+
component: (
44+
<CheckboxWithDesc
45+
checked={values.preserveAttributes}
46+
onChange={(value) => updateField('preserveAttributes', value)}
47+
title={t('xmlBeautifier.options.preserveAttributesTitle')}
48+
description={t('xmlBeautifier.options.preserveAttributesDesc')}
49+
/>
50+
)
51+
}
52+
];
53+
3554
return (
3655
<ToolContent
3756
title={title}
@@ -52,12 +71,12 @@ export default function XmlBeautifier({
5271
}
5372
initialValues={initialValues}
5473
exampleCards={exampleCards}
55-
getGroups={null}
74+
getGroups={getGroups}
5675
setInput={setInput}
5776
compute={compute}
5877
toolInfo={{
59-
title: t('xmlBeautifier.toolInfo.title', { title }),
60-
description: longDescription
78+
title: t('xmlBeautifier.toolInfo.title'),
79+
description: t('xmlBeautifier.toolInfo.description')
6180
}}
6281
/>
6382
);

‎src/pages/tools/xml/xml-beautifier/service.ts‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import { InitialValuesType } from './types';
22
import { XMLParser, XMLBuilder, XMLValidator } from 'fast-xml-parser';
33

4-
export function beautifyXml(
5-
input: string,
6-
_options: InitialValuesType
7-
): string {
4+
export function beautifyXml(input: string, options: InitialValuesType): string {
85
const valid = XMLValidator.validate(input);
96
if (valid !== true) {
107
if (typeof valid === 'object' && valid.err) {
118
return `Invalid XML: ${valid.err.msg} (line ${valid.err.line}, col ${valid.err.col})`;
129
}
1310
return 'Invalid XML';
1411
}
12+
13+
const { preserveAttributes } = options;
1514
try {
16-
const parser = new XMLParser();
15+
const parser = new XMLParser({ ignoreAttributes: !preserveAttributes });
1716
const obj = parser.parse(input);
18-
const builder = new XMLBuilder({ format: true, indentBy: ' ' });
17+
const builder = new XMLBuilder({
18+
format: true,
19+
indentBy: ' ',
20+
ignoreAttributes: !preserveAttributes
21+
});
1922
return builder.build(obj);
2023
} catch (e: any) {
2124
return `Invalid XML: ${e.message}`;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export type InitialValuesType = {
2-
// splitSeparator: string;
2+
preserveAttributes: boolean;
33
};

‎src/pages/tools/xml/xml-beautifier/xml-beautifier.service.test.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ import { beautifyXml } from './service';
44
describe('xml-beautifier', () => {
55
it('beautifies valid XML', () => {
66
const input = '<root><a>1</a><b>2</b></root>';
7-
const result = beautifyXml(input, {});
7+
const result = beautifyXml(input, { preserveAttributes: true });
88
expect(result).toContain('<root>');
99
expect(result).toContain(' <a>1</a>');
1010
expect(result).toContain(' <b>2</b>');
1111
});
1212

13+
it('preserves attributes while beautifying XML', () => {
14+
const input = '<root><user id="42" role="admin">Alice</user></root>';
15+
const result = beautifyXml(input, { preserveAttributes: true });
16+
17+
expect(result).toContain('<user id="42" role="admin">Alice</user>');
18+
});
19+
1320
it('returns error for invalid XML', () => {
1421
const input = '<root><a>1</b></root>';
15-
const result = beautifyXml(input, {});
22+
const result = beautifyXml(input, { preserveAttributes: true });
1623
expect(result).toMatch(/Invalid XML/i);
1724
});
1825
});

0 commit comments

Comments
 (0)