diff --git a/node.go b/node.go index b2c96c2..28f3f54 100644 --- a/node.go +++ b/node.go @@ -27,6 +27,8 @@ const ( CommentNode // AttributeNode is an attribute of element. AttributeNode + // NotationNode is a directive represents in document (for example, ). + NotationNode ) type Attr struct { @@ -157,6 +159,9 @@ func outputXML(b *strings.Builder, n *Node, preserveSpaces bool, config *outputC b.WriteString("-->") } return + case NotationNode: + fmt.Fprintf(b, "", n.Data) + return case DeclarationNode: b.WriteString("` + n := &Node{Data: `DOCTYPE people_list SYSTEM "example.dtd"`, Type: NotationNode} + if v := n.OutputXML(true); expected != v { + t.Errorf(`expected "%s", obtained "%s"`, expected, v) + } +} diff --git a/parse.go b/parse.go index 56a53e7..daf7233 100644 --- a/parse.go +++ b/parse.go @@ -281,6 +281,17 @@ func (p *parser) parse() (*Node, error) { } p.prev = node case xml.Directive: + node := &Node{Type: NotationNode, Data: string(tok), level: p.level} + if p.level == p.prev.level { + AddSibling(p.prev, node) + } else if p.level > p.prev.level { + AddChild(p.prev, node) + } else if p.level < p.prev.level { + for i := p.prev.level - p.level; i > 1; i-- { + p.prev = p.prev.Parent + } + AddSibling(p.prev.Parent, node) + } } } } diff --git a/parse_test.go b/parse_test.go index 28a8d1a..8633015 100644 --- a/parse_test.go +++ b/parse_test.go @@ -623,3 +623,36 @@ func TestStreamParser_DefaultNamespace(t *testing.T) { x = `ObjectD` testOutputXML(t, "third call result", x, n) } + +func TestDirective(t *testing.T) { + s := ` + + + + Q Light Controller Plus + 4.12.3 + + ` + doc, err := Parse(strings.NewReader(s)) + if err != nil { + t.Fatal(err.Error()) + } + + top := doc.FirstChild + n := top.NextSibling.NextSibling + if n == nil { + t.Error("should be not nil, but got nil") + return + } + if v := n.Type; v != NotationNode { + t.Errorf("expected the node type is NotationNode, but got %d", v) + } + if expected, val := ``, n.OutputXML(true); expected != val { + t.Errorf("expected %s but got %s", expected, val) + } + + list := Find(doc, `//*`) + if m := len(list); m != 4 { + t.Errorf("expected count is 4 but got %d", m) + } +} diff --git a/query.go b/query.go index 9f2493f..d1353aa 100644 --- a/query.go +++ b/query.go @@ -156,7 +156,7 @@ func (x *NodeNavigator) NodeType() xpath.NodeType { switch x.curr.Type { case CommentNode: return xpath.CommentNode - case TextNode, CharDataNode: + case TextNode, CharDataNode, NotationNode: return xpath.TextNode case DeclarationNode, DocumentNode: return xpath.RootNode