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.Data)
default:
diff --git a/node_test.go b/node_test.go
index c5be5b9..02b35d9 100644
--- a/node_test.go
+++ b/node_test.go
@@ -634,3 +634,11 @@ func TestNodeLevel(t *testing.T) {
}
}
+
+func TestDirectiveNode(t *testing.T) {
+ expected := ``
+ 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 = ``
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