An XML parsing library written in MoonBit that converts XML strings into structured data, supporting elements, attributes, comments, CDATA, and processing instructions.
let str =
#|<?xml version="1.0"?>
#|<root>
#| Text before
#| <child empty="true"/>
#| Text between
#| <?php echo "processing instruction" ?>
#| <![CDATA[Preserving <tags> in CDATA]]>
#| <!-- A comment here -->
#| <child>
#| Nested text
#| <grandchild />
#| More nested text
#| </child>
#| Text after
#|</root>
let xml = @parser.xml_from_string(str)
let xml = @parser.xml_from_iter(str.iter())
let (xml, ctx) = @parser.xml_from_string_with_ctx(str)
let xml = xml.unwrap()
println(xml)impl Show for AttlistDeclpub(all) enum ChildrenContentSpecOp {
Optional
ZeroOrMore
OneOrMore
}impl Show for ChildrenContentSpecOpimpl Show for ContentParticlefn ContentParticle::inner(self : ContentParticle) -> (SingleContentParticle, ChildrenContentSpecOp?)pub(all) enum DefaultDecl {
Required
Implied
Fixed(String)
Value(String)
}impl Show for DefaultDeclpub(all) struct DocTypeDecl {
name : String
externalID : ExternalID?
intSubset : Array[DTDStatement]?
}impl Show for DocTypeDeclimpl Show for EntityDeclpub(all) enum EntityDef {
EntityValue(String)
GExternalID(ExternalID, String?)
PExternalID(ExternalID)
}pub(all) struct Location {
index : Int
line : Int
column : Int
length : Int
}pub(all) enum MarkUpDecl {
ElementDecl(ElementDecl)
AttListDecl(AttlistDecl)
EntityDecl(EntityDecl)
NotationDecl(NotationDecl)
PI(String)
Comment(String)
}impl Show for MarkUpDeclpub(all) enum SingleContentParticle {
Name(String)
Seq(Array[ContentParticle])
Choice(Array[ContentParticle])
}impl Show for SingleContentParticlepub(all) enum XMLChildren {
Element(XMLElement)
Reference(String)
CDATA(String)
PI(String)
Comment(String)
Text(String)
WhiteSpace(String)
}impl Show for XMLChildrenpub(all) struct XMLDocument {
version : String
encoding : String
standalone : Bool
dtd : DocTypeDecl?
root : XMLElement
}pub(all) struct XMLElement {
name : String
empty_element : Bool
attributes : Map[String, String]
children : Array[XMLChildren]
}pub(all) enum XMLErrorKind {
SyntaxError
ValidationError
EncodingError
MalformedReference
MismatchedTags(String, String)
InternalParserError
}impl Show for XMLErrorKindpub(all) type XMLParser[Token, Value] (Seq[Token], XMLParserContext) -> ((Value, Seq[Token])?, XMLParseError?, XMLParserContext)fn[Token, Value] XMLParser::inner(self : XMLParser[Token, Value]) -> ((Seq[Token], XMLParserContext) -> ((Value, Seq[Token])?, XMLParseError?, XMLParserContext))fn[Token, Value] XMLParser::new(f : (Seq[Token], XMLParserContext) -> ((Value, Seq[Token])?, XMLParseError?, XMLParserContext)) -> XMLParser[Token, Value]fn[Token, Value] XMLParser::run(self : XMLParser[Token, Value], seq : Seq[Token], ctx : XMLParserContext) -> ((Value, Seq[Token])?, XMLParseError?, XMLParserContext)pub struct XMLParserContext {
input_array : Array[Char]
index : Int
line_number : Int
column_number : Int
errors : Array[XMLParseError]
warnings : Array[String]
}impl Show for XMLParserContext let result = pEntityRef().run(@combinator.Seq::from_string("<"))
inspect(result, content="Some((\"<\", ))") let result = pattribute().run(@combinator.Seq::from_string("name=\"value\""))
inspect(result, content="Some(((\"name\", \"value\"), ))") let result = pattributes().run(
@combinator.Seq::from_string(" name=\"value\" type=\"text\""),
)
let attrs = result.unwrap().0
inspect(attrs.get("name"), content="Some(\"value\")")
inspect(attrs.get("type"), content="Some(\"text\")") let input = "<![CDATA[Some <raw> XML & content]]>"
let result = pcdata().run(@combinator.Seq::from_string(input))
inspect(result, content="Some((\"Some <raw> XML & content\", ))")
let input = "<![CDATA[]]>"
let result = pcdata().run(@combinator.Seq::from_string(input))
inspect(result, content="Some((\"\", ))") let decimal = pcharRef().run(@combinator.Seq::from_string("{"))
let hex = pcharRef().run(@combinator.Seq::from_string("¥"))
inspect(decimal, content="Some((\"#123;\", ))")
inspect(hex, content="Some((\"#A5;\", ))") let comment = "<!-- This is a comment -->"
let result = pcomment().run(@combinator.Seq::from_string(comment))
inspect(result, content="Some((\" This is a comment \", ))") let result = pdtd().run(@combinator.Seq::from_string("<!DOCTYPE html>")).unwrap().0
inspect(result, content="<!DOCTYPE html>") // Parse a simple XML element with attributes and text content
let input = "<user id=\"1\" name=\"John\">Hello, World!</user>"
let result = pelement().run(@combinator.Seq::from_string(input))
let element = result.unwrap().0
inspect(element.name, content="user")
inspect(element.attributes.get("id"), content="Some(\"1\")")
inspect(element.attributes.get("name"), content="Some(\"John\")") // Valid XML names
let result1 = pname().run(@combinator.Seq::from_string("element1"))
inspect(result1, content="Some((\"element1\", ))")
// Invalid XML names (starting with digit)
let result2 = pname().run(@combinator.Seq::from_string("1element"))
inspect(result2, content="None") let result = ppi().run(@combinator.Seq::from_string("<?php echo 'Hello' ?>"))
inspect(result, content="Some((\"php echo 'Hello' \", ))")
let result = ppi().run(@combinator.Seq::from_string("<??>"))
inspect(result, content="Some((\"\", ))")
let result = ppi().run(@combinator.Seq::from_string("<?incomplete"))
inspect(result, content="None") // Entity reference
let entity = preference().run(@combinator.Seq::from_string("&"))
inspect(entity, content="Some((\"&\", ))")
// Character reference (decimal)
let decimal = preference().run(@combinator.Seq::from_string(" "))
inspect(decimal, content="Some((\"#32;\", ))")
// Character reference (hexadecimal)
let hex = preference().run(@combinator.Seq::from_string(" "))
inspect(hex, content="Some((\"#20;\", ))") let result = ptext().run(@combinator.Seq::from_string("Hello World"))
inspect(result, content="Some((\"Hello World\", ))")
let result = ptext().run(@combinator.Seq::from_string("Text with & and <"))
inspect(result, content="Some((\"Text with \", '&'' ''a''n''d'' ''<'))") // stops parsing at '&'
let result = ptext().run(@combinator.Seq::from_string(""))
inspect(result, content="Some((\"\", ))") let result = pwhite_space().run(@combinator.Seq::from_string(" \t\n\rtext"))
inspect(result, content="Some((\" \\t\\n\\r\", 't''e''x''t'))") let xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><child>Text</child></root>"
let result = pxml().run(@combinator.Seq::from_string(xml))
let doc = result.unwrap().0
inspect(doc.version, content="1.0")
inspect(doc.root.name, content="root") let xml = "<?xml version=\"1.0\"?><root><child>Content</child></root>"
let doc = xml_from_string(xml).unwrap()
inspect(doc.root.name, content="root")Install
Download zipAn XML parsing library written in MoonBit that converts XML strings into structured data, supporting elements, attributes, comments, CDATA, and processing instructions.