A reckoner seed: xml's parse and write, a node as a tagged list — machines/seeds/seedxml.shoddy
seedxml bridges xml into the
reckoner, Shoddy’s stack calculator. Rule R4.16 says there is no TREE
cell at the keyboard. So an Xml node converts to a tagged LIST,
one shape per case: { "elem" tag attrs kids },
{ "comment" text } and so on. The one exception is
XText, which travels as a plain STRING. An element’s
attributes are a dict — a list of name-and-value pairs — the
same shape seeddict already established.
XcOfXml/XcToXml, the conversion functions, are
Included by seedhtml rather than duplicated,
since html.shoddy answers the same Xml type.
The guard this seed adds is not the parse — it is everything
around it. xml.shoddy’s reader already answers a Result
rather than aborting on bad syntax. And XMLLOAD and
XMLSAVE go through TRYREADFILE and
TRYWRITEFILE rather than the aborting whole-file builtins. So
a path that is not there, a directory handed where a file was meant, or an
unwritable destination is a refusal or an honest False.
The larger thing it buys is that a parsed tree needs no words of its own. An element is a tagged LIST and its attributes are the same LIST-of-PAIR dict seeddict established. So the dictionary a session already has walks it:
FIRST and NTH take the tag or the children.DGET reads an attribute.MAP and FILTER run over the child list.A seed that invented XMLATTR would have added a second
spelling of a word that was already there.
Parse, and write back out. The round trip is exact for anything xml itself will accept:
> "<note><to>batley</to></note>" XMLPARSE XMLTEXT
x: "<note><to>batley</to></note>"
> CLEAR "<note><to>batley</to></note>" XMLPARSE 2 XMLPRETTY
x: "<note>
<to>batley</to>
</note>
"
Attributes need single quotes when they are typed. The
reckoner’s tokenizer — the part that cuts a line into words
— has no escape inside a string literal. So there is no way to put a
" inside one, and the usual XML spelling of an attribute is
quoted. XML accepts either quote. The apostrophe form is therefore the one
that can be typed, and it is written back out in the conventional form:
> "<a b='1'>hi</a>" XMLPARSE XMLTEXT
x: "<a b="1">hi</a>"
For anything longer than a line, XMLLOAD is the way in and
the quoting question does not arise.
The two refusals come from different places and say so. The first is xml’s own reader naming where the syntax went wrong. The second is the guarded read:
> "<a><b></a>" XMLPARSE
?: XMLPARSE: </a> CLOSES <b> AT 7
> "nope.xml" XMLLOAD
?: XMLLOAD: cannot read the file
| Word | Description |
|---|---|
| XMLPARSE ( str -- doc ) | The string, parsed as XML — an element is { "elem" tag attrs kids }, attrs a dict. |
| XMLTEXT ( doc -- str ) | The value, written out as XML text. |
| XMLPRETTY ( doc n -- str ) | The value, written out as XML text indented n spaces per level. |
| XMLLOAD ( path -- doc ) | The file, read and parsed as XML — a refusal names why it could not be, whether that is the file or the syntax. |
| XMLSAVE ( path doc -- ok ) | Write the value to path as XML text; True on success. |
| User | How | |
|---|---|---|
| halifax | The calculator's XML words: XMLPARSE, XMLTEXT, XMLPRETTY, XMLLOAD and XMLSAVE. | |
| seedhtml | Includes this seed to reuse XcOfXml/XcToXml for the same Xml type html.shoddy answers. | |
| sparky | Sparky folds it too, so a model calling eval reaches the same words halifax puts at a prompt. |
| Machine | Why | |
|---|---|---|
| cuttle | The Cell type every bridged word reads its arguments from and answers into. | |
| reckoner | RckReg, RckSeeding and the argument readers every registered word is built from. | |
| seq | List plumbing under the tree converters. | |
| xml | The domain this seed bridges: XmlRead, XmlText, XmlPretty. |