-! Copyright (C) 2005, 2006 Daniel Ehrenberg
+! Copyright (C) 2005, 2009 Daniel Ehrenberg
! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences sequences.private assocs arrays
delegate.protocols delegate vectors accessors multiline
-macros words quotations combinators slots fry ;
+macros words quotations combinators slots fry strings ;
IN: xml.data
-TUPLE: name space main url ;
+UNION: nullable-string string POSTPONE: f ;
+
+TUPLE: name
+ { space nullable-string }
+ { main string }
+ { url nullable-string } ;
C: <name> name
: ?= ( object/f object/f -- ? )
: assure-name ( string/name -- name )
dup name? [ <null-name> ] unless ;
-TUPLE: opener name attrs ;
-C: <opener> opener
-
-TUPLE: closer name ;
-C: <closer> closer
-
-TUPLE: contained name attrs ;
-C: <contained> contained
-
-TUPLE: comment text ;
-C: <comment> comment
-
-TUPLE: directive ;
-
-TUPLE: element-decl < directive name content-spec ;
-C: <element-decl> element-decl
-
-TUPLE: attlist-decl < directive name att-defs ;
-C: <attlist-decl> attlist-decl
-
-TUPLE: entity-decl < directive name def pe? ;
-C: <entity-decl> entity-decl
-
-TUPLE: system-id system-literal ;
-C: <system-id> system-id
-
-TUPLE: public-id pubid-literal system-literal ;
-C: <public-id> public-id
-
-TUPLE: doctype-decl < directive name external-id internal-subset ;
-C: <doctype-decl> doctype-decl
-
-TUPLE: notation-decl < directive name id ;
-C: <notation-decl> notation-decl
-
-TUPLE: instruction text ;
-C: <instruction> instruction
-
-TUPLE: prolog version encoding standalone ;
-C: <prolog> prolog
-
-TUPLE: attrs alist ;
+TUPLE: attrs { alist sequence } ;
C: <attrs> attrs
: attr@ ( key alist -- index {key,value} )
INSTANCE: attrs assoc
-TUPLE: tag name attrs children ;
+TUPLE: opener { name name } { attrs attrs } ;
+C: <opener> opener
+
+TUPLE: closer { name name } ;
+C: <closer> closer
+
+TUPLE: contained { name name } { attrs attrs } ;
+C: <contained> contained
+
+TUPLE: comment { text string } ;
+C: <comment> comment
+
+TUPLE: directive ;
+
+TUPLE: element-decl < directive
+ { name string } { content-spec string } ;
+C: <element-decl> element-decl
+
+TUPLE: attlist-decl < directive
+ { name string } { att-defs string } ;
+C: <attlist-decl> attlist-decl
+
+UNION: boolean t POSTPONE: f ;
+
+TUPLE: entity-decl < directive
+ { name string }
+ { def string }
+ { pe? boolean } ;
+C: <entity-decl> entity-decl
+
+TUPLE: system-id { system-literal string } ;
+C: <system-id> system-id
+
+TUPLE: public-id { pubid-literal string } { system-literal string } ;
+C: <public-id> public-id
+
+UNION: id system-id public-id POSTPONE: f ;
+
+TUPLE: doctype-decl < directive
+ { name string }
+ { external-id id }
+ { internal-subset sequence } ;
+C: <doctype-decl> doctype-decl
+
+TUPLE: notation-decl < directive name id ;
+C: <notation-decl> notation-decl
+
+TUPLE: instruction { text string } ;
+C: <instruction> instruction
+
+TUPLE: prolog
+ { version string }
+ { encoding string }
+ { standalone boolean } ;
+C: <prolog> prolog
+
+TUPLE: tag
+ { name name }
+ { attrs attrs }
+ { children sequence } ;
: <tag> ( name attrs children -- tag )
[ assure-name ] [ T{ attrs } assoc-like ] [ ] tri*
M: tag clone
tag clone-slots ;
-TUPLE: xml prolog before body after ;
+TUPLE: xml
+ { prolog prolog }
+ { before sequence }
+ { body tag }
+ { after sequence } ;
C: <xml> xml
CONSULT: sequence-protocol xml body>> ;
-USING: kernel xml sequences assocs tools.test io arrays namespaces
-accessors xml.data xml.utilities xml.writer generic sequences.deep ;
+USING: kernel xml sequences assocs tools.test io arrays namespaces fry
+accessors xml.data xml.utilities xml.writer generic sequences.deep multiline ;
IN: xml.tests
: sub-tag
! Example
-: sample-doc ( -- string )
- {
- "<html xmlns:f='http://littledan.onigirihouse.com/namespaces/replace'>"
- "<body>"
- "<span f:sub='foo'/>"
- "<div f:sub='bar'/>"
- "<p f:sub='baz'>paragraph</p>"
- "</body></html>"
- } concat ;
+STRING: sample-doc
+<html xmlns:f='http://littledan.onigirihouse.com/namespaces/replace'>
+<body>
+<span f:sub='foo'/>
+<div f:sub='bar'/>
+<p f:sub='baz'>paragraph</p>
+</body></html>
+;
+
+STRING: expected-result
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns:f="http://littledan.onigirihouse.com/namespaces/replace">
+ <body>
+ <span f:sub="foo">
+ foo
+ </span>
+ <div f:sub="bar">
+ blah
+ <a/>
+ </div>
+ <p f:sub="baz"/>
+ </body>
+</html>
+;
: test-refs ( -- string )
[
H{
{ "foo" { "foo" } }
- { "bar" { "blah" T{ tag f T{ name f "" "a" "" } f f } } }
+ { "bar" { "blah" T{ tag f T{ name f "" "a" "" } T{ attrs } f } } }
{ "baz" f }
} ref-table set
- sample-doc string>xml dup template xml>string
+ sample-doc string>xml dup template pprint-xml>string
] with-scope ;
-[ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><html xmlns:f=\"http://littledan.onigirihouse.com/namespaces/replace\"><body><span f:sub=\"foo\">foo</span><div f:sub=\"bar\">blah<a/></div><p f:sub=\"baz\"/></body></html>" ] [ test-refs ] unit-test
+expected-result '[ _ ] [ test-refs ] unit-test