@@ -17,18 +17,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
1818import * as saxes from "@rubensworks/saxes" ;
1919import { createCDataSectionNode , createNode } from "./factory" ;
20- import { Attributes , BasicValue , TextNode , getNodeClass , JDita , BaseNode , DocumentNode , DocTypeDecl , CDataNode , AbstractBaseNode , XMLDecl } from "@evolvedbinary/lwdita-ast" ;
20+ import { Attributes , BasicValue , TextNode , getNodeClass , JDita , BaseNode , DocumentNode , DocTypeDecl , CDataNode , AbstractBaseNode , XMLDecl , NonAcceptedChildError , UnknownAttributeError } from "@evolvedbinary/lwdita-ast" ;
2121import { InMemoryTextSimpleOutputStreamCollector } from "./stream" ;
2222import { XditaSerializer } from "./xdita-serializer" ;
23+ import { formatErrorMessage } from "./utils" ;
2324
2425/**
2526 * Converts XML to an AST document tree
2627 *
2728 * @param xml - XML string
28- * @param abortOnError - If true, abort on error
29+ * @param abortOnFirstError - If true, abort on first error
2930 * @returns - Promise of a DocumentNode
3031 */
31- export async function xditaToAst ( xml : string , abortOnError = true ) : Promise < DocumentNode > {
32+ export async function xditaToAst ( xml : string , abortOnFirstError = true ) : Promise < DocumentNode > {
3233 return new Promise ( ( resolve , reject ) => {
3334 const errors : Error [ ] = [ ] ;
3435 // Create a Parser Object
@@ -79,7 +80,15 @@ export async function xditaToAst(xml: string, abortOnError = true): Promise<Docu
7980
8081 const node : BaseNode = createNode ( text ) ;
8182 // add the text node to the parent
82- stack [ stack . length - 1 ] . add ( node , abortOnError ) ;
83+ try {
84+ stack [ stack . length - 1 ] . add ( node , abortOnFirstError ) ;
85+ } catch ( e ) {
86+ if ( e instanceof NonAcceptedChildError ) {
87+ errorHandler ( e ) ;
88+ } else {
89+ throw e
90+ }
91+ }
8392 } ) ;
8493
8594 // Look for the first open tag `<` and add the node to the array
@@ -110,11 +119,15 @@ export async function xditaToAst(xml: string, abortOnError = true): Promise<Docu
110119 */
111120 parser . on ( "opentag" , function ( node : saxes . SaxesTagNS ) {
112121 try {
113- const obj = createNode ( node ) ;
114- stack [ stack . length - 1 ] . add ( obj , abortOnError ) ;
115- stack . push ( obj ) ;
122+ const obj = createNode ( node ) ;
123+ stack [ stack . length - 1 ] . add ( obj , abortOnFirstError ) ;
124+ stack . push ( obj ) ;
116125 } catch ( e ) {
117- console . log ( 'invalid:' , e ) ;
126+ if ( e instanceof NonAcceptedChildError || e instanceof UnknownAttributeError ) {
127+ errorHandler ( e , node . name ) ;
128+ } else {
129+ throw e
130+ }
118131 }
119132 } ) ;
120133
@@ -127,24 +140,37 @@ export async function xditaToAst(xml: string, abortOnError = true): Promise<Docu
127140 parser . on ( "cdata" , ( cdata ) => {
128141 try {
129142 const obj = createCDataSectionNode ( cdata ) ;
130- stack [ stack . length - 1 ] . add ( obj , abortOnError ) ;
143+ stack [ stack . length - 1 ] . add ( obj , abortOnFirstError ) ;
131144 } catch ( e ) {
132- console . log ( 'invalid:' , e ) ;
145+ if ( e instanceof NonAcceptedChildError ) {
146+ errorHandler ( e , "CDATA" ) ;
147+ } else {
148+ throw e
149+ }
133150 }
134151 } )
135152
136153 // return the document tree if run without errors
137154 parser . on ( "end" , function ( ) {
138- if ( errors . length && abortOnError ) {
155+ if ( errors . length ) {
139156 reject ( errors ) ;
140157 } else {
141158 resolve ( doc ) ;
142159 }
143160 } ) ;
144161
145- parser . on ( "error" , function ( e ) {
162+ function errorHandler ( e : Error , nodeName ?: string ) {
163+ e . message = formatErrorMessage ( e . message , stack , parser . line , parser . column , nodeName )
164+ if ( abortOnFirstError ) {
165+ reject ( e . message )
166+ // This is necessary to stop the parsing
167+ throw e ;
168+ }
146169 errors . push ( e ) ;
147- } ) ;
170+ }
171+
172+ // Error handler for XML
173+ parser . on ( "error" , errorHandler ) ;
148174
149175 // process the xml using the parser
150176 parser . write ( xml ) . close ( ) ;
@@ -155,11 +181,11 @@ export async function xditaToAst(xml: string, abortOnError = true): Promise<Docu
155181 * Convert the document tree to JDita object
156182 *
157183 * @param xml - The XML input as string
158- * @param abortOnError - Boolean, if true, stop execution and report errors
184+ * @param abortOnFirstError - Boolean, if true, stop execution and report errors
159185 * @returns JDita object
160186 */
161- export async function xditaToJdita ( xml : string , abortOnError = true ) : Promise < JDita > {
162- return xditaToAst ( xml , abortOnError ) . then ( astToJdita ) ;
187+ export async function xditaToJdita ( xml : string , abortOnFirstError = true ) : Promise < JDita > {
188+ return xditaToAst ( xml , abortOnFirstError ) . then ( astToJdita ) ;
163189}
164190
165191/**
0 commit comments