@@ -11,80 +11,34 @@ function readDocType(xmlData, i){
11
11
{
12
12
i = i + 9 ;
13
13
let angleBracketsCount = 1 ;
14
- let hasBody = false , entity = false , comment = false ;
14
+ let hasBody = false , comment = false ;
15
15
let exp = "" ;
16
16
for ( ; i < xmlData . length ; i ++ ) {
17
- if ( xmlData [ i ] === '<' && ! comment ) {
18
- if ( hasBody &&
19
- xmlData [ i + 1 ] === '!' &&
20
- xmlData [ i + 2 ] === 'E' &&
21
- xmlData [ i + 3 ] === 'N' &&
22
- xmlData [ i + 4 ] === 'T' &&
23
- xmlData [ i + 5 ] === 'I' &&
24
- xmlData [ i + 6 ] === 'T' &&
25
- xmlData [ i + 7 ] === 'Y'
26
- ) {
27
- i += 7 ;
28
- entity = true ;
29
- } else if ( hasBody &&
30
- xmlData [ i + 1 ] === '!' &&
31
- xmlData [ i + 2 ] === 'E' &&
32
- xmlData [ i + 3 ] === 'L' &&
33
- xmlData [ i + 4 ] === 'E' &&
34
- xmlData [ i + 5 ] === 'M' &&
35
- xmlData [ i + 6 ] === 'E' &&
36
- xmlData [ i + 7 ] === 'N' &&
37
- xmlData [ i + 8 ] === 'T'
38
- ) {
39
- //Not supported
40
- i += 8 ;
41
- } else if ( hasBody &&
42
- xmlData [ i + 1 ] === '!' &&
43
- xmlData [ i + 2 ] === 'A' &&
44
- xmlData [ i + 3 ] === 'T' &&
45
- xmlData [ i + 4 ] === 'T' &&
46
- xmlData [ i + 5 ] === 'L' &&
47
- xmlData [ i + 6 ] === 'I' &&
48
- xmlData [ i + 7 ] === 'S' &&
49
- xmlData [ i + 8 ] === 'T'
50
- ) {
51
- //Not supported
52
- i += 8 ;
53
- } else if ( hasBody &&
54
- xmlData [ i + 1 ] === '!' &&
55
- xmlData [ i + 2 ] === 'N' &&
56
- xmlData [ i + 3 ] === 'O' &&
57
- xmlData [ i + 4 ] === 'T' &&
58
- xmlData [ i + 5 ] === 'A' &&
59
- xmlData [ i + 6 ] === 'T' &&
60
- xmlData [ i + 7 ] === 'I' &&
61
- xmlData [ i + 8 ] === 'O' &&
62
- xmlData [ i + 9 ] === 'N'
63
- ) {
64
- //Not supported
65
- i += 9 ;
66
- } else if ( //comment
67
- xmlData [ i + 1 ] === '!' &&
68
- xmlData [ i + 2 ] === '-' &&
69
- xmlData [ i + 3 ] === '-'
70
- ) {
71
- comment = true ;
72
- } else {
73
- throw new Error ( "Invalid DOCTYPE" ) ;
17
+ if ( xmlData [ i ] === '<' && ! comment ) { //Determine the tag type
18
+ if ( hasBody && isEntity ( xmlData , i ) ) {
19
+ i += 7 ;
20
+ [ entityName , val , i ] = readEntityExp ( xmlData , i + 1 ) ;
21
+ if ( val . indexOf ( "&" ) === - 1 ) //Parameter entities are not supported
22
+ entities [ entityName ] = {
23
+ regx : RegExp ( `&${ entityName } ;` , "g" ) ,
24
+ val : val
25
+ } ;
74
26
}
27
+ else if ( hasBody && isElement ( xmlData , i ) ) i += 8 ; //Not supported
28
+ else if ( hasBody && isAttlist ( xmlData , i ) ) i += 8 ; //Not supported
29
+ else if ( hasBody && isNotation ( xmlData , i ) ) i += 9 ; //Not supported
30
+ else if ( isComment ) comment = true ;
31
+ else throw new Error ( "Invalid DOCTYPE" ) ;
32
+
75
33
angleBracketsCount ++ ;
76
34
exp = "" ;
77
- } else if ( xmlData [ i ] === '>' ) {
35
+ } else if ( xmlData [ i ] === '>' ) { //Read tag content
78
36
if ( comment ) {
79
37
if ( xmlData [ i - 1 ] === "-" && xmlData [ i - 2 ] === "-" ) {
80
38
comment = false ;
81
39
angleBracketsCount -- ;
82
40
}
83
41
} else {
84
- if ( entity ) {
85
- parseEntityExp ( exp , entities ) ;
86
- entity = false ;
87
- }
88
42
angleBracketsCount -- ;
89
43
}
90
44
if ( angleBracketsCount === 0 ) {
@@ -105,14 +59,85 @@ function readDocType(xmlData, i){
105
59
return { entities, i} ;
106
60
}
107
61
108
- const entityRegex = RegExp ( "^\\s([a-zA-z0-0]+)[ \t](['\"])([^&]+)\\2" ) ;
109
- function parseEntityExp ( exp , entities ) {
110
- const match = entityRegex . exec ( exp ) ;
111
- if ( match ) {
112
- entities [ match [ 1 ] ] = {
113
- regx : RegExp ( `&${ match [ 1 ] } ;` , "g" ) ,
114
- val : match [ 3 ]
115
- } ;
62
+ function readEntityExp ( xmlData , i ) {
63
+ //External entities are not supported
64
+ // <!ENTITY ext SYSTEM "http://normal-website.com" >
65
+
66
+ //Parameter entities are not supported
67
+ // <!ENTITY entityname "&anotherElement;">
68
+
69
+ //Internal entities are supported
70
+ // <!ENTITY entityname "replacement text">
71
+
72
+ //read EntityName
73
+ let entityName = "" ;
74
+ for ( ; i < xmlData . length && ( xmlData [ i ] !== "'" && xmlData [ i ] !== '"' ) ; i ++ ) {
75
+ // if(xmlData[i] === " ") continue;
76
+ // else
77
+ entityName += xmlData [ i ] ;
78
+ }
79
+ entityName = entityName . trim ( ) ;
80
+ if ( entityName . indexOf ( " " ) !== - 1 ) throw new Error ( "External entites are not supported" ) ;
81
+
82
+ //read Entity Value
83
+ const startChar = xmlData [ i ++ ] ;
84
+ let val = ""
85
+ for ( ; i < xmlData . length && xmlData [ i ] !== startChar ; i ++ ) {
86
+ val += xmlData [ i ] ;
116
87
}
88
+ return [ entityName , val , i ] ;
117
89
}
90
+
91
+ function isComment ( xmlData , i ) {
92
+ if ( xmlData [ i + 1 ] === '!' &&
93
+ xmlData [ i + 2 ] === '-' &&
94
+ xmlData [ i + 3 ] === '-' ) return true
95
+ return false
96
+ }
97
+ function isEntity ( xmlData , i ) {
98
+ if ( xmlData [ i + 1 ] === '!' &&
99
+ xmlData [ i + 2 ] === 'E' &&
100
+ xmlData [ i + 3 ] === 'N' &&
101
+ xmlData [ i + 4 ] === 'T' &&
102
+ xmlData [ i + 5 ] === 'I' &&
103
+ xmlData [ i + 6 ] === 'T' &&
104
+ xmlData [ i + 7 ] === 'Y' ) return true
105
+ return false
106
+ }
107
+ function isElement ( xmlData , i ) {
108
+ if ( xmlData [ i + 1 ] === '!' &&
109
+ xmlData [ i + 2 ] === 'E' &&
110
+ xmlData [ i + 3 ] === 'L' &&
111
+ xmlData [ i + 4 ] === 'E' &&
112
+ xmlData [ i + 5 ] === 'M' &&
113
+ xmlData [ i + 6 ] === 'E' &&
114
+ xmlData [ i + 7 ] === 'N' &&
115
+ xmlData [ i + 8 ] === 'T' ) return true
116
+ return false
117
+ }
118
+
119
+ function isAttlist ( xmlData , i ) {
120
+ if ( xmlData [ i + 1 ] === '!' &&
121
+ xmlData [ i + 2 ] === 'A' &&
122
+ xmlData [ i + 3 ] === 'T' &&
123
+ xmlData [ i + 4 ] === 'T' &&
124
+ xmlData [ i + 5 ] === 'L' &&
125
+ xmlData [ i + 6 ] === 'I' &&
126
+ xmlData [ i + 7 ] === 'S' &&
127
+ xmlData [ i + 8 ] === 'T' ) return true
128
+ return false
129
+ }
130
+ function isNotation ( xmlData , i ) {
131
+ if ( xmlData [ i + 1 ] === '!' &&
132
+ xmlData [ i + 2 ] === 'N' &&
133
+ xmlData [ i + 3 ] === 'O' &&
134
+ xmlData [ i + 4 ] === 'T' &&
135
+ xmlData [ i + 5 ] === 'A' &&
136
+ xmlData [ i + 6 ] === 'T' &&
137
+ xmlData [ i + 7 ] === 'I' &&
138
+ xmlData [ i + 8 ] === 'O' &&
139
+ xmlData [ i + 9 ] === 'N' ) return true
140
+ return false
141
+ }
142
+
118
143
module . exports = readDocType ;
0 commit comments