relaxng

package module
v0.0.0-...-607165c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2018 License: Apache-2.0 Imports: 13 Imported by: 0

README

#Translates RelaxNG to Katydid

Translates Simplified RelaxNG Grammars to the Katydid Relapse Grammar.

There is a playground available here http://katydid.github.io/relaxng/play/

Simplification is defined at these two resources:

Usage

simplifiedRelaxNG := `
<grammar>
    <start>
        <ref name="element1"></ref>
    </start>
    <define name="element1">
        <element>
            <name>foo</name>
            <empty></empty>
        </element>
    </define>
</grammar>`
relaxing, _ := ParseGrammar([]byte(simplifiedRelaxNG))
relapse, _ := Translate(relaxing)
input := "<foo/>"
if err := Validate(relapse, []byte(input)); err != nil {
    fmt.Println("invalid")
}
fmt.Println("valid")
// Output: valid

For more see the go package documentation

RelaxNG Test Suite

Build Status

passed: 146
failed: 0
namespace tests skipped: 13
datatypeLibrary tests skipped: 1
incorrect grammars skipped: 213

Steps:

  • The RelaxNG Test Suite is run through the simplifier which also eliminates all the incorrect grammars.
  • Next these simplified RelaxNG XML Grammars are parsed and translated to Katydid Relapse.
  • Finally the translated Relapse is used to validate the XML.

Viewing all tests can be done in the playground by going to this link, which will load the first test, and then clicking the NextTest button.

Example 1

The Simplified RelaxNG Grammar

<grammar>
    <start>
        <ref name="element1"></ref>
    </start>
    <define name="element1">
        <element>
            <name>foo</name>
            <empty></empty>
        </element>
    </define>
</grammar>

is translated to this Relapse Grammar

@element1
#element1={
    elem_foo:(<empty>|@ws);
    (@ws)*;
}
#ws=->whitespace($string)
#text=->anytext($string)

Example 2

The Simplified RelaxNG Grammar

<grammar>
    <start>
        <ref name="element1"></ref>
    </start>
    <define name="element1">
        <element>
            <name>foo</name>
            <attribute>
                <name>bar</name>
                <text></text>
            </attribute>
        </element>
    </define>
</grammar>

is translated to this Relapse Grammar

@element1
#element1={
    elem_foo:attr_bar:(@text)*;
    (@ws)*;
}
#ws=->whitespace($string)
#text=->anytext($string)

Example 3

The Simplified RelaxNG Grammar

<grammar>
    <start>
        <ref name="element1"></ref>
    </start>
    <define name="element1">
        <element>
            <name>foo</name>
            <choice>
                <group>
                    <attribute>
                        <name>bar</name>
                        <empty></empty>
                    </attribute>
                    <ref name="element2"></ref>
                </group>
                <group>
                    <attribute>
                        <name>bar</name>
                        <text></text>
                    </attribute>
                    <ref name="element3"></ref>
                </group>
            </choice>
        </element>
    </define>
    <define name="element2">
        <element>
            <name>baz1</name>
            <empty></empty>
        </element>
    </define>
    <define name="element3">
        <element>
            <name>baz2</name>
            <empty></empty>
        </element>
    </define>
</grammar>

is translated to this Relapse Grammar

@element1
#element1={
    elem_foo:(
        [
            attr_bar:@ws,
            @element2
        ] |
        [
            attr_bar:(@text)*,
            @element3
        ]
    );
    (@ws)*;
}
#element2={
    elem_baz1:(<empty>|@ws);
    (@ws)*;
}
#element3={
    elem_baz2:(<empty>|@ws);
    (@ws)*;
}
#ws=->whitespace($string)
#text=->anytext($string)

Known Issues

There are quite a few known issues:

  • Only simplified grammars are supported.
  • namespaces are not supported.
  • datatypes: only string and token are currently supported.
  • datatypeLibraries are not supported.

I don't really intend to fix these, but you never know.

Only handles simplified relaxng grammars.

http://www.kohsuke.org/relaxng/rng2srng/ seems to be quite effective at converting the full spectrum of what is possible within the relaxng grammar to the simplified grammar.

java -jar rng2srng.jar full.rng > simplified.rng

Documentation

Overview

Translates RelaxNG to Katydid Relapse

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnyText

func AnyText(S funcs.String) funcs.Bool

func ListFunc

func ListFunc(S funcs.String, Expr funcs.ConstString) (funcs.Bool, error)

func NewXMLParser

func NewXMLParser() xml.XMLParser

func RemoveTODOs

func RemoveTODOs(g *Grammar)

The function removes the ns attributes with value TODO. These ns="TODO" attributes can become present after converting from RelaxNG to Simplified RelaxNG using rng2srng.jar

func TextFunc

func TextFunc(S funcs.String, C funcs.ConstString) (funcs.Bool, error)

func Token

func Token(S funcs.String, C funcs.ConstString) (funcs.Bool, error)

func Translate

func Translate(g *Grammar) (*ast.Grammar, error)

Translates a parsed RelaxNG Grammar into a Katydid Relapse Grammar.

func Validate

func Validate(katydid *ast.Grammar, xmlContent []byte) error

Validates input xml against a Katydid Relapse Grammar.

Example

Parses the simplified RelaxNG Grammar, translates it to relapse and then validates the input xml.

simplifiedRelaxNG := `
	<grammar>
	    <start>
	        <ref name="element1"></ref>
	    </start>
	    <define name="element1">
	        <element>
	            <name>foo</name>
	            <empty></empty>
	        </element>
	    </define>
	</grammar>`
relaxing, _ := ParseGrammar([]byte(simplifiedRelaxNG))
relapse, _ := Translate(relaxing)
input := "<foo/>"
if err := Validate(relapse, []byte(input)); err != nil {
	fmt.Println("invalid")
}
fmt.Println("valid")
Output:

valid

func Whitespace

func Whitespace(S funcs.String) funcs.Bool

Types

type AnyNameClass

type AnyNameClass struct {
	XMLName xml.Name       `xml:"anyName"`
	Except  *NameOrPattern `xml:"except"`
}

The anyNameClass RelaxNG grammar element.

type Data

type Data struct {
	XMLName         xml.Name       `xml:"data"`
	Type            string         `xml:"type,attr"`
	DatatypeLibrary string         `xml:"datatypeLibrary,attr"`
	Param           []Param        `xml:"param"`
	Except          *NameOrPattern `xml:"except"`
}

The data RelaxNG grammar element which is described here: http://books.xmlschemata.org/relaxng/ch17-77040.html http://books.xmlschemata.org/relaxng/relax-CHP-8-SECT-1.html Even though katydid could easily support more types, only Type string and token are currently supported. This also means that Param is not currently supported. DatatypeLibrary is not supported.

func (*Data) IsString

func (this *Data) IsString() bool

Returns whether this data type is a string type. Only type string and type token are supported. An empty Type value implies a default value of token.

type Define

type Define struct {
	Name string `xml:"name,attr"`
	//Left is Name and Right is Pattern
	Element Pair `xml:"element"`
}

The define RelaxNG grammar element

type Empty

type Empty struct {
	XMLName xml.Name `xml:"empty"`
}

The empty RelaxNG grammar element.

type Grammar

type Grammar struct {
	XMLName xml.Name       `xml:"grammar"`
	Start   *NameOrPattern `xml:"start"`
	Define  []Define       `xml:"define"`
}

The simplified RelaxNG Grammar as specified in http://relaxng.org/spec-20011203.html

grammar	  		::=  <grammar> <start> top </start> define* </grammar>
define	  		::=  <define name="NCName"> <element> nameClass top </element> </define>
top	  			::=  <notAllowed/>
				| Pattern
Pattern	  		::=  <empty/>
				| Pattern
Pattern	  		::=  <text/>
				| <data type="NCName" datatypeLibrary="anyURI"> param* [exceptPattern] </data>
				| <value datatypeLibrary="anyURI" type="NCName" ns="string"> string </value>
				| <list> Pattern </list>
				| <attribute> nameClass Pattern </attribute>
				| <ref name="NCName"/>
				| <oneOrMore> Pattern </oneOrMore>
				| <choice> Pattern Pattern </choice>
				| <group> Pattern Pattern </group>
				| <interleave> Pattern Pattern </interleave>
param	  		::=  <param name="NCName"> string </param>
exceptPattern	::=  <except> Pattern </except>
nameClass	  	::=  <anyName> [exceptNameClass] </anyName>
				| <nsName ns="string"> [exceptNameClass] </nsName>
				| <name ns="string"> NCName </name>
				| <choice> nameClass nameClass </choice>
exceptNameClass	::= <except> nameClass </except>

func ParseGrammar

func ParseGrammar(buf []byte) (*Grammar, error)

Parses simplified RelaxNG XML into a Grammar structure.

func (*Grammar) String

func (g *Grammar) String() string

type List

type List struct {
	XMLName xml.Name `xml:"list"`
	*NameOrPattern
}

The list RelaxNG grammar element which is described here: http://books.xmlschemata.org/relaxng/relax-CHP-7-SECT-9.html http://books.xmlschemata.org/relaxng/ch17-77136.html

type NameNameClass

type NameNameClass struct {
	XMLName xml.Name `xml:"name"`
	Ns      string   `xml:"ns,attr"`
	Text    string   `xml:",chardata"`
}

The name RelaxNG grammar element. Ns is not supported.

type NameOrPattern

type NameOrPattern struct {
	NotAllowed *NotAllowed `xml:"notAllowed"`
	Empty      *Empty      `xml:"empty"`
	Text       *Text       `xml:"text"`
	Data       *Data       `xml:"data"`
	Value      *Value      `xml:"value"`
	List       *List       `xml:"list"`
	//Attribute does not care about order, left is Name and Right is Pattern
	Attribute *Pair      `xml:"attribute"`
	Ref       *Ref       `xml:"ref"`
	OneOrMore *OneOrMore `xml:"oneOrMore"`
	Choice    *Pair      `xml:"choice"`
	//http://books.xmlschemata.org/relaxng/relax-CHP-6-SECT-1.html
	//  Because the order of attributes isn't considered significant by the XML 1.0 specification,
	//  the meaning of the group compositor is slightly less straightforward than it appears at first.
	//  Here's the semantic quirk: the group compositor says,
	//  "Check that the patterns included in this compositor appear in the specified order,
	//  except for attributes, which are allowed to appear in any order in the start tag."
	Group      *Pair `xml:"group"`
	Interleave *Pair `xml:"interleave"`

	AnyName *AnyNameClass  `xml:"anyName"`
	NsName  *NsNameClass   `xml:"nsName"`
	Name    *NameNameClass `xml:"name"`
}

One of the name or pattern RelaxNG grammar elements

func (*NameOrPattern) IsNameClass

func (this *NameOrPattern) IsNameClass() bool

func (*NameOrPattern) IsPattern

func (this *NameOrPattern) IsPattern() bool

func (*NameOrPattern) String

func (this *NameOrPattern) String() string

type NotAllowed

type NotAllowed struct {
	XMLName xml.Name `xml:"notAllowed"`
}

The notAllowed RelaxNG grammar element.

type NsNameClass

type NsNameClass struct {
	XMLName xml.Name       `xml:"nsName"`
	Ns      string         `xml:"ns,attr"`
	Except  *NameOrPattern `xml:"except"`
}

The nsName RelaxNG grammar element. This element is not supported.

type OneOrMore

type OneOrMore struct {
	XMLName xml.Name `xml:"oneOrMore"`
	*NameOrPattern
}

The oneOrMore RelaxNG grammar element.

type Pair

type Pair struct {
	Left  *NameOrPattern
	Right *NameOrPattern
}

A pair of RelaxNG grammar elements.

func (*Pair) MarshalXML

func (this *Pair) MarshalXML(e *xml.Encoder, start xml.StartElement) error

func (*Pair) UnmarshalXML

func (this *Pair) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Param

type Param struct {
	Name string `xml:",attr"`
	Text string `xml:",chardata"`
}

The param RelaxNG grammar element.

type Ref

type Ref struct {
	XMLName xml.Name `xml:"ref"`
	Name    string   `xml:"name,attr"`
}

The ref RelaxNG grammar element.

type Text

type Text struct {
	XMLName xml.Name `xml:"text"`
}

The text RelaxNG grammar element.

type Value

type Value struct {
	XMLName         xml.Name `xml:"value"`
	DatatypeLibrary string   `xml:"datatypeLibrary,attr"`
	Type            string   `xml:"type,attr"`
	Ns              string   `xml:"ns,attr"`
	Text            string   `xml:",chardata"`
}

The value RelaxNG grammar element which is described here: http://books.xmlschemata.org/relaxng/ch17-77225.html Match a value in a text node. DatatypeLibrary and Ns fields are not supported.

func (*Value) IsString

func (this *Value) IsString() bool

Returns whether this value type is a string type. http://books.xmlschemata.org/relaxng/relax-CHP-7-SECT-4.html Only type string and type token are supported. An empty Type value implies a default value of token.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL