! Copyright (C) 2005, 2009 Daniel Ehrenberg ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays io io.encodings.binary io.files io.streams.string kernel namespaces sequences strings io.encodings.utf8 xml.data xml.errors xml.elements ascii xml.entities xml.writer xml.state xml.autoencoding assocs xml.tokenize xml.name ; IN: xml > ] [ attrs>> ] bi add-child ; M: opener process push-xml ; : check-closer ( name opener -- name opener ) dup [ unopened ] unless 2dup name>> = [ name>> swap mismatched ] unless ; M: closer process name>> pop-xml first2 [ check-closer attrs>> ] dip add-child ; : init-xml-stack ( -- ) V{ } clone xml-stack set extra-entities [ H{ } assoc-like ] change f push-xml ; : default-prolog ( -- prolog ) "1.0" "UTF-8" f ; : reset-prolog ( -- ) default-prolog prolog-data set ; : init-xml ( -- ) reset-prolog init-xml-stack init-ns-stack ; : assert-blanks ( seq pre? -- ) swap [ string? ] filter [ dup [ blank? ] all? [ drop ] [ swap pre/post-content ] if ] each drop ; : no-pre/post ( pre post -- pre post/* ) ! this does *not* affect the contents of the stack [ dup t assert-blanks ] [ dup f assert-blanks ] bi* ; : no-post-tags ( post -- post/* ) ! this does *not* affect the contents of the stack dup [ tag? ] contains? [ multitags ] when ; : assure-tags ( seq -- seq ) ! this does *not* affect the contents of the stack [ notags ] unless* ; : make-xml-doc ( prolog seq -- xml-doc ) dup [ tag? ] find [ assure-tags cut rest no-pre/post no-post-tags ] dip swap ; ! * Views of XML SYMBOL: text-now? PRIVATE> TUPLE: pull-xml scope ; : ( -- pull-xml ) [ input-stream [ ] change ! bring var in this scope init-parser reset-prolog init-ns-stack text-now? on ] H{ } make-assoc pull-xml boa ; ! pull-xml needs to call start-document somewhere : pull-event ( pull -- xml-event/f ) scope>> [ text-now? get [ parse-text f ] [ get-char [ make-tag t ] [ f f ] if ] if text-now? set ] bind ; : pull-elem ( pull -- xml-elem/f ) [ init-xml-stack (pull-elem) ] with-scope ; : each-element ( stream quot: ( xml-elem -- ) -- ) swap [ reset-prolog init-ns-stack start-document [ call-under ] when* xml-loop ] with-state ; inline : (read-xml) ( -- ) start-document [ process ] when* [ process ] xml-loop ; inline : (read-xml-chunk) ( stream -- prolog seq ) [ init-xml (read-xml) done? [ unclosed ] unless xml-stack get first second prolog-data get swap ] with-state ; : read-xml ( stream -- xml ) 0 depth [ (read-xml-chunk) make-xml-doc ] with-variable ; : read-xml-chunk ( stream -- seq ) 1 depth [ (read-xml-chunk) nip ] with-variable ; : string>xml ( string -- xml ) t string-input? [ read-xml ] with-variable ; : string>xml-chunk ( string -- xml ) t string-input? [ read-xml-chunk ] with-variable ; : file>xml ( filename -- xml ) binary read-xml ; : read-dtd ( stream -- dtd ) [ reset-prolog H{ } clone extra-entities set take-internal-subset ] with-state ; : file>dtd ( filename -- dtd ) utf8 read-dtd ; : string>dtd ( string -- dtd ) read-dtd ;