예제 #1
0
파일: xmlenum.go 프로젝트: jmhodges/xmlenum
func recurse(p *xml.Parser, name string, m TagMap) os.Error {
	// depth++ // debugging
	for {
		// if depth > maxDepth { // debugging
		// 	return nil
		// }
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case xml.StartElement:
			if m[t.Name.Local] == nil {
				m[t.Name.Local] = TagMap{}
			}
			err = recurse(p, t.Name.Local, m[t.Name.Local])
			if err != nil {
				return err
			}
		case xml.EndElement:
			// If ending the element we entered recurse for, return
			if t.Name.Local == name {
				return nil
			}
		}
	}
	return nil
}
예제 #2
0
// Scan XML token stream for next element and save into val.
// If val == nil, allocate new element based on proto map.
// Either way, return val.
func next(p *xml.Parser) (xml.Name, interface{}, os.Error) {
	// Read start element to find out what type we want.
	se, err := nextStart(p)
	if err != nil {
		return xml.Name{}, nil, err
	}

	// Put it in an interface and allocate one.
	var nv interface{}
	switch se.Name.Space + " " + se.Name.Local {
	case nsStream + " features":
		nv = &streamFeatures{}
	case nsStream + " error":
		nv = &streamError{}
	case nsTLS + " starttls":
		nv = &tlsStartTLS{}
	case nsTLS + " proceed":
		nv = &tlsProceed{}
	case nsTLS + " failure":
		nv = &tlsFailure{}
	case nsSASL + " mechanisms":
		nv = &saslMechanisms{}
	case nsSASL + " challenge":
		nv = ""
	case nsSASL + " response":
		nv = ""
	case nsSASL + " abort":
		nv = &saslAbort{}
	case nsSASL + " success":
		nv = &saslSuccess{}
	case nsSASL + " failure":
		nv = &saslFailure{}
	case nsBind + " bind":
		nv = &bindBind{}
	case nsClient + " message":
		nv = &clientMessage{}
	case nsClient + " presence":
		nv = &clientPresence{}
	case nsClient + " iq":
		nv = &clientIQ{}
	case nsClient + " error":
		nv = &clientError{}
	default:
		return xml.Name{}, nil, os.ErrorString("unexpected XMPP message " +
			se.Name.Space + " <" + se.Name.Local + "/>")
	}

	// Unmarshal into that storage.
	if err = p.Unmarshal(nv, &se); err != nil {
		return xml.Name{}, nil, err
	}
	return se.Name, nv, err
}
예제 #3
0
// Scan XML token stream to find next StartElement.
func nextStart(p *xml.Parser) (xml.StartElement, os.Error) {
	for {
		t, err := p.Token()
		if err != nil {
			log.Fatal("token", err)
		}
		switch t := t.(type) {
		case xml.StartElement:
			return t, nil
		}
	}
	panic("unreachable")
}
예제 #4
0
func getTagContents(parser *xml.Parser) string {
	tag, err := parser.Token()
	if err != nil {
		return ""
	}
	switch dtype := tag.(type) {
	case xml.CharData:
		bytes := xml.CharData(dtype)
		text := string([]byte(bytes))
		return text
	}
	return ""
}
예제 #5
0
파일: xmlenum.go 프로젝트: jmhodges/xmlenum
func start(p *xml.Parser, name string, m TagMap) os.Error {
	for {
		// if depth > maxDepth { // debugging
		// 	return nil
		// }
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case xml.StartElement:
			if t.Name.Local == name {
				if _, found := m[name]; !found {
					m[name] = TagMap{}
				}
				err = recurse(p, name, m[name])
			}
		}
		if err != nil {
			return err
		}
	}
	return nil
}
예제 #6
0
파일: parser.go 프로젝트: vdobler/ft
func parse(tok xml.Token, parser *xml.Parser, parent *Node) (node *Node, err os.Error) {
	node = new(Node)
	node.Parent = parent
	st, _ := tok.(xml.StartElement)
	node.Name = st.Name.Local
	trace("parsing tag %s", node.Name)
	node.Attr = []html.Attribute{}
	for _, attr := range st.Attr {
		a := html.Attribute{Key: attr.Name.Local, Val: attr.Value}
		node.Attr = append(node.Attr, a)
	}

	// var childs vector.Vector
	// var chld []*Node

	for done := false; !done; {
		var tok xml.Token
		tok, err = parser.Token()
		if err != nil {
			if err == os.EOF {
				err = nil
				break
			}
			if node.Name == "script" {
				err = os.ErrorString("Javascript: " + err.String())
			}
			return
		}
		switch t := tok.(type) {
		case xml.StartElement:
			var ch *Node
			ch, err = parse(t, parser, node)
			if err != nil {
				return
			}
			node.Child = append(node.Child, ch)
			node.subs = append(node.subs, ch)
			if node.Full != "" {
				node.Full += " "
			}
			node.Full += ch.Full
		case xml.EndElement:
			if t.Name.Local != node.Name {
				fmt.Printf("Tag " + node.Name + " closed by " + t.Name.Local + "\n")
			}
			done = true
		case xml.CharData:
			b := bytes.NewBuffer([]byte(t))
			s := b.String()
			ct := " " + cleanText(s)
			node.Text += ct
			node.Full += ct
			node.subs = append(node.subs, &Node{Parent: node, Name: TEXT_NODE, Text: s})
		case xml.Comment, xml.Directive, xml.ProcInst:
			// skip
		default:
			fmt.Printf("Very strange:\nType = %t\n Value = %#v\n", tok, tok)
		}
	}

	node.Text = strings.Trim(node.Text, " \n\t\r")
	node.Full = cleanText(node.Full)

	prepareClasses(node)

	trace("Made Node: " + node.String() + "\n")
	return
}