11<template >
2- <div style =" height : 100% ;" >
3- <div class =" xml-viewer" >
4- <div v-if =" loading" >Đang tải...</div >
5- <template v-else >
6- <TreeView v-if =" parsedObject" :data =" parsedObject" />
7- </template >
8- </div >
2+ <div v-if =" loading" >Đang tải...</div >
3+ <div v-else class =" xml-viewer-container" >
4+ <TreeView v-if =" parsedObject" :data =" parsedObject" />
95 </div >
106</template >
117
128<style scoped>
13- .xml-viewer {
9+ .xml-viewer-container {
1410 overflow-y : auto ;
1511 max-height : 100% ;
1612 border-radius : 6px ;
2319}
2420 </style >
2521
22+
23+
2624<script lang="ts">
2725import { defineComponent , ref , onMounted } from ' vue' ;
2826import TreeView from ' ./TreeView.vue' ;
@@ -40,85 +38,61 @@ export default defineComponent({
4038 const error = ref (' ' );
4139
4240 function domToObj(node : Node ): any {
43- if (node .nodeType === 8 ) {
44- const comment = node .nodeValue ?.trim ();
45- return comment ? { ' #comment' : comment } : undefined ;
46- }
41+ // Nếu là text node
4742 if (node .nodeType === 3 ) {
4843 const text = node .nodeValue ?.trim ();
4944 return text ? text : undefined ;
5045 }
46+ // Nếu là element node
5147 if (node .nodeType === 1 ) {
5248 const obj: any = {};
5349 const el = node as Element ;
54-
50+ // Thuộc tính
5551 if (el .attributes && el .attributes .length > 0 ) {
5652 obj [' @attributes' ] = {};
5753 for (let attr of Array .from (el .attributes )) {
5854 obj [' @attributes' ][attr .name ] = attr .value ;
5955 }
6056 }
61-
57+ // Child nodes
6258 for (let child of Array .from (node .childNodes )) {
6359 const childObj = domToObj (child );
6460 if (childObj === undefined ) continue ;
65-
6661 if (child .nodeType === 3 ) {
62+ // text node
6763 if (! obj [' #text' ]) obj [' #text' ] = ' ' ;
6864 obj [' #text' ] += childObj ;
6965 } else if (child .nodeType === 1 ) {
70- const tag = (child as Element ).tagName ;
66+ // element node
67+ const childEl = child as Element ;
68+ const tag = childEl .tagName ;
7169 if (! obj [tag ]) obj [tag ] = [];
7270 obj [tag ].push (childObj );
73- } else if (child .nodeType === 8 ) {
74- if (! obj [' #comment' ]) obj [' #comment' ] = [];
75- obj [' #comment' ].push (childObj [' #comment' ]);
7671 }
7772 }
78-
73+ // Nếu chỉ có 1 phần tử trong mảng thì trả về object thay vì array
7974 for (let key in obj ) {
8075 if (Array .isArray (obj [key ]) && obj [key ].length === 1 ) {
8176 obj [key ] = obj [key ][0 ];
8277 }
8378 }
84-
8579 return obj ;
8680 }
8781 return undefined ;
8882 }
8983
90- function domListToArray(nodeList : NodeList ): any {
91- const arr: any [] = [];
92- let elementCount = 0 ;
93-
94- for (let node of Array .from (nodeList )) {
95- if (node .nodeType === 1 ) {
96- elementCount ++ ;
97- arr .push ({ [node .nodeName ]: domToObj (node ) });
98- } else {
99- const obj = domToObj (node );
100- if (obj !== undefined ) arr .push (obj );
101- }
102- }
103-
104- if (elementCount === 1 && arr .length === 1 ) {
105- return arr [0 ];
106- }
107- return arr ;
108- }
109-
11084 const fetchXml = async () => {
11185 loading .value = true ;
11286 error .value = ' ' ;
11387 try {
11488 const res = await fetch (props .url );
11589 if (! res .ok ) throw new Error (' Không thể tải XML' );
116-
11790 xmlContent .value = await res .text ();
11891 const parser = new DOMParser ();
11992 const xmlDoc = parser .parseFromString (xmlContent .value , ' text/xml' );
120-
121- parsedObject .value = domListToArray (xmlDoc .childNodes );
93+ // Lấy node gốc
94+ const root = xmlDoc .documentElement ;
95+ parsedObject .value = { [root .tagName ]: domToObj (root ) };
12296 } catch (e : any ) {
12397 error .value = e .message || ' Lỗi không xác định' ;
12498 } finally {
@@ -128,6 +102,7 @@ export default defineComponent({
128102
129103 onMounted (fetchXml );
130104
105+
131106 return { xmlContent , parsedObject , loading , error };
132107 }
133108});
0 commit comments