Proof of Concept - Converter of XML to alternative formats (see the description of the idea).
In short, it's easy to design formats alternative to XML that are oriented to search/query, simple parsing (even with Bash), etc. This Common Lisp is just a simple proof of concept, demonstrating conversion of XML to 2 such alternative formats: REGFMT and CMDFMT:
- REGFMT is oriented to simple querying with grep, awk, etc. Conceptually it reminds lines of Windows .reg files
- CMDFMT is oriented to simple parsing with awk, Bash and similar. Conceptually consists of short lines perfect for parsing with FSM.
Considering such XML:
<?xml version="1.0"?>
<!DOCTYPE root [
<!ELEMENT root (#PCDATA | lib)*>
<!ATTLIST root id ID #REQUIRED>
<!ELEMENT lib (#PCDATA | book | xxx)*>
<!ELEMENT book (#PCDATA)>
<!ELEMENT xxx EMPTY>
<!NOTATION png SYSTEM "image/png">
<!ENTITY internal "InternalEntityValue">
<!ENTITY ext SYSTEM "external.xml">
<!ENTITY logo SYSTEM "logo.png" NDATA png>
]>
<root xmlns="urn:default" xmlns:x="urn:x" id="r1">
<!-- A comment -->
<![CDATA[Some CDATA text]]>
<?pi processing instruction?>
Text & more 😀 &internal;
<lib xmlns="urn:yyy">
<book>Book1</book>
<book>Book2</book>
<xxx/>
</lib>
Other text!!!
<lib>
<book>Book3</book>
</lib>
</root>we can get such REGFMT analogue:
::<children> = 3
::<comment> = <<>!DOCTYPE root SYSTEM "t1.dtd"<>>
<dtd>::<name> = root
<dtd>::<element>::<name> = root
<dtd>::<element>::<model> = (* (OR PCDATA lib))
<dtd>::<attribute>::<element-name> = root
<dtd>::<attribute>::<attribute-name> = id
<dtd>::<attribute>::<type> = ID
<dtd>::<attribute>::<default> = REQUIRED
<dtd>::<element>::<name> = lib
<dtd>::<element>::<model> = (* (OR PCDATA book xxx))
<dtd>::<element>::<name> = book
<dtd>::<element>::<model> = PCDATA
<dtd>::<element>::<name> = xxx
<dtd>::<element>::<model> = EMPTY
<dtd>::<notation>::<name> = png
<dtd>::<notation>::<system-id> = image/png
<dtd>::<internal-entity>::<kind> = GENERAL
<dtd>::<internal-entity>::<name> = internal
<dtd>::<internal-entity>::<value> = InternalEntityValue
<dtd>::<external-entity>::<kind> = GENERAL
<dtd>::<external-entity>::<name> = ext
<dtd>::<external-entity>::<system-id> = external.xml
<dtd>::<unparsed-entity>::<name> = logo
<dtd>::<unparsed-entity>::<system-id> = logo.png
<dtd>::<unparsed-entity>::<notation-name> = png
root::<children> = 7
root::<namespace-uri> = urn:default
root::<qname> = root
root::<prefix-mapping> = urn:yyy
root::<prefix-mapping>::x = urn:x
root::<prefix-mapping> = urn:default
root::@xmlns = urn:default
root::@xmlns::<namespace-uri> = http://www.w3.org/2000/xmlns/
root::@xmlns:x = urn:x
root::@xmlns:x::<local-name> = x
root::@xmlns:x::<namespace-uri> = http://www.w3.org/2000/xmlns/
root::@id = r1
root::@id::<local-name> = id
root::<comment> = A comment
root::<cdata> = Some CDATA text
root::<processing-instruction>::pi = processing instruction
root::<text> = Text & more 😀InternalEntityValue
root::<0>::lib::<children> = 3
root::<0>::lib::<namespace-uri> = urn:yyy
root::<0>::lib::<qname> = lib
root::<0>::lib::<prefix-mapping> = urn:yyy
root::<0>::lib::<prefix-mapping>::x = urn:x
root::<0>::lib::<prefix-mapping> = urn:default
root::<0>::lib::@xmlns = urn:yyy
root::<0>::lib::@xmlns::<namespace-uri> = http://www.w3.org/2000/xmlns/
root::<0>::lib::<0>::book::<children> = 1
root::<0>::lib::<0>::book::<namespace-uri> = urn:yyy
root::<0>::lib::<0>::book::<qname> = book
root::<0>::lib::<0>::book::<prefix-mapping> = urn:yyy
root::<0>::lib::<0>::book::<prefix-mapping>::x = urn:x
root::<0>::lib::<0>::book::<prefix-mapping> = urn:default
root::<0>::lib::<0>::book::<text> = Book1
root::<0>::lib::<1>::book::<children> = 1
root::<0>::lib::<1>::book::<namespace-uri> = urn:yyy
root::<0>::lib::<1>::book::<qname> = book
root::<0>::lib::<1>::book::<prefix-mapping> = urn:yyy
root::<0>::lib::<1>::book::<prefix-mapping>::x = urn:x
root::<0>::lib::<1>::book::<prefix-mapping> = urn:default
root::<0>::lib::<1>::book::<text> = Book2
root::<0>::lib::xxx::<namespace-uri> = urn:yyy
root::<0>::lib::xxx::<qname> = xxx
root::<0>::lib::xxx::<prefix-mapping> = urn:yyy
root::<0>::lib::xxx::<prefix-mapping>::x = urn:x
root::<0>::lib::xxx::<prefix-mapping> = urn:default
root::<text> = Other text!!!
root::<1>::lib::<children> = 1
root::<1>::lib::<namespace-uri> = urn:default
root::<1>::lib::<qname> = lib
root::<1>::lib::book::<children> = 1
root::<1>::lib::book::<namespace-uri> = urn:default
root::<1>::lib::book::<qname> = book
root::<1>::lib::book::<text> = Book3
similar to CMDFMT:
.COM
<!DOCTYPE root SYSTEM "t1.dtd">
.COME
.DTD
.DTD.NAME root
.DTD.EL.NAME root
.DTD.EL.MODEL (* (OR PCDATA lib))
.DTD.ATTR.EL.NAME root
.DTD.ATTR.ATTR.NAME id
.DTD.ATTR.TYPE ID
.DTD.ATTR.DEF REQUIRED
.DTD.EL.NAME lib
.DTD.EL.MODEL (* (OR PCDATA book xxx))
.DTD.EL.NAME book
.DTD.EL.MODEL PCDATA
.DTD.EL.NAME xxx
.DTD.EL.MODEL EMPTY
.DTD.NOTA.NAME png
.DTD.NOTA.SYS.ID image/png
.DTD.INT.ENT.KIND GENERAL
.DTD.INT.ENT.NAME internal
.DTD.INT.ENT.VALUE InternalEntityValue
.DTD.EXT.ENT.KIND GENERAL
.DTD.EXT.ENT.NAME ext
.DTD.EXT.SYS.ID external.xml
.DTD.UNP.ENT.NAME logo
.DTD.UNP.ENT.SYS.ID logo.png
.DTD.UNP.ENT.NOTA.NAME png
.DTDE
.EL 7 root
.EL.NS urn:default
.EL.LOC.NAME root
.EL.QNAME root
.EL.PREF.MAP NIL urn:yyy
.EL.PREF.MAP x urn:x
.EL.PREF.MAP NIL urn:default
.EL.ATTR xmlns urn:default http://www.w3.org/2000/xmlns/ T
.EL.ATTR x xmlns:x urn:x http://www.w3.org/2000/xmlns/ T
.EL.ATTR id id r1 T
.COM
A comment
.COME
.CD
Some CDATA text
.CDE
.PI.TARG pi
.PI
processing instruction
.PIE
.TEXT
Text & more 😀InternalEntityValue
.TEXTE
.EL 3 root/lib
.EL.NS urn:yyy
.EL.LOC.NAME lib
.EL.QNAME lib
.EL.PREF.MAP NIL urn:yyy
.EL.PREF.MAP x urn:x
.EL.PREF.MAP NIL urn:default
.EL.ATTR xmlns urn:yyy http://www.w3.org/2000/xmlns/ T
.EL 1 root/lib/book
.EL.NS urn:yyy
.EL.LOC.NAME book
.EL.QNAME book
.EL.PREF.MAP NIL urn:yyy
.EL.PREF.MAP x urn:x
.EL.PREF.MAP NIL urn:default
.TEXT
Book1
.TEXTE
.ELE root/lib/book
.EL 1 root/lib/book
.EL.NS urn:yyy
.EL.LOC.NAME book
.EL.QNAME book
.EL.PREF.MAP NIL urn:yyy
.EL.PREF.MAP x urn:x
.EL.PREF.MAP NIL urn:default
.TEXT
Book2
.TEXTE
.ELE root/lib/book
.EL 0 root/lib/xxx
.EL.NS urn:yyy
.EL.LOC.NAME xxx
.EL.QNAME xxx
.EL.PREF.MAP NIL urn:yyy
.EL.PREF.MAP x urn:x
.EL.PREF.MAP NIL urn:default
.ELE root/lib/xxx
.ELE root/lib
.TEXT
Other text!!!
.TEXTE
.EL 1 root/lib
.EL.NS urn:default
.EL.LOC.NAME lib
.EL.QNAME lib
.EL 1 root/lib/book
.EL.NS urn:default
.EL.LOC.NAME book
.EL.QNAME book
.TEXT
Book3
.TEXTE
.ELE root/lib/book
.ELE root/lib
.ELE root
Select all text nodes from root/**/lib/:
$ ./xmlalt -i t1.xml --from XMLFMT --to REGFMT|grep 'root::.*::lib.*::<text>'
root::<0>::lib::<0>::book::<text> = Book1
root::<0>::lib::<1>::book::<text> = Book2
root::<1>::lib::book::<text> = Book3You need Linux, MacOS or WSL, Cygwin...
- Install SBCL, qlot
- Run
qlot installto obtain all dependencies (seeqlfile) - Run
qlot exec ./build.sh
Deserialization for CMDFMT, REGFMT to be able to convert CMDFMT to XML or to REGFMT, etc. They should be able to deserialize partial files where it makes sense.