예제 #1
0
// TransformXML parses the XML tree, traverses it and calls TransformFunc
// on each XML token, writing the output to the writer, resulting in a
// transformed XML tree
func TransformXML(decoder *xml.Decoder, encoder *xml.Encoder, fn TransformFunc) error {
	parentNodes := &NodeList{}
	for {
		token, err := decoder.Token()
		if err != nil {
			if err != io.EOF {
				return trace.Wrap(err)
			}
			break
		}
		for _, t := range fn(parentNodes, token) {
			if err := encoder.EncodeToken(t); err != nil {
				return err
			}
		}
		switch e := token.(type) {
		case xml.StartElement:
			parentNodes.Push(e)
		case xml.EndElement:
			parentNodes.Pop()
		}
	}
	encoder.Flush()
	return nil
}
예제 #2
0
파일: main.go 프로젝트: seikichi/gopl
func NewTree(dec *xml.Decoder) (Node, error) {
	var stack []*Element // stack of elements
	var result *Element
	for {
		tok, err := dec.Token()
		if err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		}

		switch tok := tok.(type) {
		case xml.StartElement:
			newElem := &Element{tok.Name, tok.Attr, []Node{}}
			if len(stack) > 0 {
				elem := stack[len(stack)-1]
				elem.Children = append(elem.Children, newElem)
			}
			stack = append(stack, newElem)
			if result == nil {
				result = newElem
			}
		case xml.EndElement:
			stack = stack[:len(stack)-1] // pop
		case xml.CharData:
			if len(stack) == 0 {
				continue
			}
			elem := stack[len(stack)-1]
			elem.Children = append(elem.Children, CharData(tok))
		}
	}
	return result, nil
}
예제 #3
0
파일: simple.go 프로젝트: voltron42/xtraml
func (x *XmlNode) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	x.Name = getName(start.Name)
	x.Attrs = map[string]string{}
	for _, attr := range start.Attr {
		x.Attrs[getName(attr.Name)] = attr.Value
	}
	token, err := d.Token()
	for token != start.End() {
		if err != nil {
			return err
		}
		next, ok := token.(xml.StartElement)
		if ok {
			child := XmlNode{}
			err = child.UnmarshalXML(d, next)
			if err != nil {
				return err
			}
			x.Children = append(x.Children, child)
		} else {
			text, ok := token.(xml.CharData)
			if ok {
				x.Children = append(x.Children, TextNode(string([]byte(text))))
			}
		}
		token, err = d.Token()
	}
	return nil
}
예제 #4
0
func readOptiongroup(attributes []xml.Attr, dec *xml.Decoder) *Optiongroup {
	og := &Optiongroup{}
	og.ShortDescription = make(map[string]string)

forloop:
	for {
		t, err := dec.Token()
		if err != nil {
			break
		}
		switch v := t.(type) {
		case xml.StartElement:
			switch v.Name.Local {
			case "shortdescription":
				lang, text := readShortDescription(v.Attr, dec)
				og.ShortDescription[lang] = text
			case "classoption":
				og.Classoption = append(og.Classoption, readClassoption(v.Attr, dec))
			}
		case xml.EndElement:
			if v.Name.Local == "optiongroup" {
				break forloop
			}
		}
	}
	return og
}
예제 #5
0
func readVariant(attributes []xml.Attr, dec *xml.Decoder) Variant {
	variant := Variant{}
	variant.Description = make(map[string]template.HTML)
	for _, attribute := range attributes {
		if attribute.Name.Local == "name" {
			variant.Name = attribute.Value
		}
	}
	for {
		t, err := dec.Token()
		if err != nil {
			break
		}
		switch v := t.(type) {
		case xml.StartElement:
			switch v.Name.Local {
			case "argument":
				variant.Arguments = append(variant.Arguments, readArgument(v.Attr, dec))
			case "description":
				lang, text := readDescription(v.Attr, dec)
				variant.Description[lang] = text
			}
		case xml.EndElement:
			if v.Name.Local == "variant" {
				return variant
			}
		}
	}
	return variant
}
예제 #6
0
파일: result.go 프로젝트: phusl/machine
func getStructMember(parser *xml.Decoder) (member Struct) {
	var token xml.Token
	token, _ = parser.Token()

	member = Struct{}

	for {
		switch t := token.(type) {
		case xml.StartElement:
			if t.Name.Local == "name" {
				member["name"], _ = getElementValue(parser)
			}

			if t.Name.Local == "value" {
				member["value"], _ = getValue(parser)
			}
		case xml.EndElement:
			if t.Name.Local == "member" {
				return member
			}
		}

		token, _ = parser.Token()
	}

	return
}
예제 #7
0
func XMLText(decoder *xml.Decoder) (string, error) {
	r := ""
	for {
		token, err := decoder.Token()
		if err == io.EOF {
			return r, io.EOF
		}

		switch token := token.(type) {
		case xml.EndElement:
			return r, nil
		case xml.CharData:
			r += string(token)
		case xml.StartElement:
			sub, err := XMLText(decoder)
			r += sub
			if err != nil {
				return r, err
			}
		case xml.Comment: // ignore
		case xml.ProcInst: // ignore
		case xml.Directive: // ignore
		default:
			panic("unknown token")
		}
	}
}
예제 #8
0
파일: taxonomy.go 프로젝트: js-arias/jdh
func readTaxonLineage(dec *xml.Decoder, tx *taxon) error {
	for tk, err := dec.Token(); ; tk, err = dec.Token() {
		if err != nil {
			return err
		}
		switch t := tk.(type) {
		case xml.StartElement:
			if t.Name.Local == "taxon" {
				for _, at := range t.Attr {
					switch at.Name.Local {
					case "taxId":
						tx.par = append(tx.par, at.Value)
					case "scientificName":
						tx.lin = append(tx.lin, at.Value)
					}

				}
			}
		case xml.EndElement:
			if t.Name.Local != "taxon" {
				return nil
			}
		}
	}
}
예제 #9
0
파일: album.go 프로젝트: mmbros/music-arc
// UnmarshalXML function unmarshal an <album-list> XML fragment to a Map[string]*Album
func (am *AlbumMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	// result
	m := map[string]*Album{}

LOOP:
	for {
		token, err := d.Token()
		if err != nil {
			return err
		}

		switch t := token.(type) {
		case xml.StartElement:

			if t.Name.Local == "album" {
				a := Album{}
				elmt := xml.StartElement(t)
				d.DecodeElement(&a, &elmt)
				m[a.ID] = &a
			}
		case xml.EndElement:
			if t.Name.Local == "album-list" {
				break LOOP
			}
		}
	}

	*am = AlbumMap(m)
	return nil
}
예제 #10
0
func readXmlText(decoder *xml.Decoder) (string, error) {
	var context string
	for {
		token, err := decoder.Token()
		if nil != err {
			return context, err
		}
		switch v := token.(type) {
		case xml.EndElement:
			return context, nil
		case xml.CharData:
			context = string(v)
		case xml.StartElement:
			switch v.Name.Local {
			case "Datetime":
				txt, e := readXmlText(decoder)
				if nil != e {
					return "", e
				}
				if e = exitElement(decoder, 0); nil != e {
					return txt, e
				}
				return txt, nil
			default:
				return context, errors.New("element '" + v.Name.Local + "' is not excepted, excepted is CharData")
			}
		default:
			return context, fmt.Errorf("token '%T' is not excepted, excepted is CharData", v)
		}
	}
}
예제 #11
0
func ReadEnvelopeHeader(decoder *xml.Decoder) (string, error) {
	var action string
	for {
		t, err := decoder.Token()
		if nil != err {
			return "", err
		}

		switch v := t.(type) {
		case xml.EndElement:
			return action, nil
		case xml.StartElement:
			switch v.Name.Local {
			case "Action":
				action, err = readXmlText(decoder)
				if nil != err {
					return "", err
				}
			default:
				if e := skipElement(decoder, 0); nil != e {
					return "", e
				}
			}
		}
	}
}
예제 #12
0
func (t *Tag) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	t.Name = start.Name
	t.Attr = start.Attr
	for {
		token, err := d.Token()
		if err != nil {
			if err == io.EOF {
				return nil
			}
			return err
		}
		switch token.(type) {
		case xml.StartElement:
			tok := token.(xml.StartElement)
			var data *Tag
			if err := d.DecodeElement(&data, &tok); err != nil {
				return err
			}
			t.Children = append(t.Children, data)
		case xml.CharData:
			t.Children = append(t.Children, token.(xml.CharData).Copy())
		case xml.Comment:
			t.Children = append(t.Children, token.(xml.Comment).Copy())
		}
	}
	return nil
}
예제 #13
0
func WalkNodePath(dec *xml.Decoder, selector string) (xml.StartElement, error) {
	if selector == "" {
		return xml.StartElement{}, errors.New("invalid path")
	}

	splitfront := func(p string) (front string, tail string) {
		i := strings.IndexRune(p, '/')
		if i >= 0 {
			return p[:i], p[i+1:]
		}
		return p, ""
	}

	var nextid string

	nextid, selector = splitfront(selector)
	for {
		token, err := dec.Token()
		if err != nil {
			return xml.StartElement{}, err
		}

		start, isStart := token.(xml.StartElement)
		if isStart && strings.EqualFold(nextid, getAttr(&start, "id")) {
			nextid, selector = splitfront(selector)
			if nextid == "" {
				return start, nil
			}
		}
	}

	panic("unreachable")
}
예제 #14
0
func getNextToken(p *xml.Decoder) (*xmlToken, error) {
	tag, err := p.Token()
	if tag == nil || err != nil {
		return nil, err
	}

	if tokenMap == nil {
		initTokenMap()
	}

	switch v := tag.(type) {
	case xml.StartElement:
		tok, err := getTagToken(v.Name.Local)
		if err != nil {
			return nil, err
		}

		return &xmlToken{token: tok, isStart: true}, nil
	case xml.EndElement:
		tok, err := getTagToken(v.Name.Local)
		if err != nil {
			return nil, err
		}

		return &xmlToken{token: tok, isStart: false}, nil
	case xml.CharData:
		return &xmlToken{token: tokenText, text: string(v)}, nil
	case xml.ProcInst:
		return &xmlToken{token: tokenProcInst}, nil
	default:
		return nil, fmt.Errorf("Not handling XML token %v (type %T)", v, v)
	}
}
예제 #15
0
파일: xml.go 프로젝트: twstrike/coyim
// Scan XML token stream to finc next Element (start or end)
func nextElement(p *xml.Decoder) (xml.Token, error) {
	for {
		t, err := p.Token()
		if err != nil {
			return xml.StartElement{}, err
		}

		switch elem := t.(type) {
		case xml.StartElement, xml.EndElement:
			return t, nil
		case xml.CharData:
			// https://xmpp.org/rfcs/rfc6120.html#xml-whitespace
			// rfc6120, section 1.4: "whitespace" is used to refer to any character
			// or characters matching [...] SP, HTAB, CR, or LF.
			switch string(elem) {
			case " ", "\t", "\r", "\n": //TODO: consider more than one whitespace
				log.Println("xmpp: received whitespace ping")
			}
		case xml.ProcInst:
			if !(elem.Target == "xml" && strings.HasPrefix(string(elem.Inst), "version=")) {
				log.Printf("xmpp: received unhandled ProcInst element: target=%s inst=%s\n", elem.Target, string(elem.Inst))
			}
		default:
			log.Printf("xmpp: received unhandled element: %#v\n", elem)
		}
	}
}
예제 #16
0
func (e *Element) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
	buf := new(bytes.Buffer)
	enc := xml.NewEncoder(buf)
	if err := enc.EncodeToken(start); err != nil {
		return err
	}
	for {
		token, err := dec.Token()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}
		if err := enc.EncodeToken(token); err != nil {
			return err
		}
	}
	if err := enc.Flush(); err != nil {
		return err
	}
	e.Name = start.Name.Local
	e.Raw = buf.Bytes()
	return nil
}
예제 #17
0
func (c *choice) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
	for {
		tok, err := dec.Token()
		if err != nil && err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		switch v := tok.(type) {
		case xml.StartElement:
			switch v.Name.Local {
			case "description":
				d := &description{}
				d.commands = c.commands
				dec.DecodeElement(d, &v)
				switch d.Lang {
				case "en":
					c.DescriptionEn = d
				case "de":
					c.DescriptionDe = d
				}
			}
		}
	}
	return nil
}
예제 #18
0
func ReadEvent(decoder *xml.Decoder) (map[string]interface{}, error) {
	results := map[string]interface{}{}
	for {
		t, err := decoder.Token()
		if nil != err {
			if io.EOF == err {
				return results, nil
			}
			return nil, err
		}

		switch v := t.(type) {
		case xml.EndElement:
			return results, nil
		case xml.StartElement:
			switch v.Name.Local {
			case "System":
				if err = ReadEventSystemElements(decoder, results); nil != err {
					return nil, err
				}
			case "EventData":
				if err = ReadEventDataElements(decoder, results); nil != err {
					return nil, err
				}
			default:
				if err = skipElement(decoder, 0); nil != err {
					return nil, err
				}
			}
		}
	}
}
예제 #19
0
파일: result.go 프로젝트: phusl/machine
func getArrayValue(parser *xml.Decoder) (result interface{}, err error) {
	var token xml.Token
	token, err = parser.Token()

	result = []interface{}{}

	for {
		switch t := token.(type) {
		case xml.StartElement:
			if t.Name.Local == "value" {
				var value interface{}
				value, err = getValue(parser)

				result = append(result.([]interface{}), value)
			}
		case xml.EndElement:
			if t.Name.Local == "array" {
				return result, err
			}
		}

		token, err = parser.Token()
	}

	return
}
func parsePropertyGroup(decoder *xml.Decoder, element xml.StartElement) (string, string) {
	outputPath, scope := "", ""
	if condition, ok := getAttrValue(element, "Condition"); ok {
		condition = strings.ToLower(condition)
		if strings.Contains(condition, "debug") {
			scope = "debug"
		} else if strings.Contains(condition, "release") {
			scope = "release"
		} else {
			return "", "unknown"
		}
	}
LOOP:
	for {
		t, _ := decoder.Token()
		if t == nil {
			break
		}
		switch se := t.(type) {
		case xml.StartElement:
			if se.Name.Local == "OutputPath" {
				outputPath = getCharData(decoder)
			}
		case xml.EndElement:
			if se.Name.Local == "PropertyGroup" {
				break LOOP
			}
		}
	}
	return outputPath, scope
}
예제 #21
0
func (ccs *CampaignCriterions) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
	cc := NegativeCampaignCriterion{}
	for token, err := dec.Token(); err == nil; token, err = dec.Token() {
		if err != nil {
			return err
		}
		switch start := token.(type) {
		case xml.StartElement:
			switch start.Name.Local {
			case "campaignId":
				if err := dec.DecodeElement(&cc.CampaignId, &start); err != nil {
					return err
				}
			case "criterion":
				criterion, err := criterionUnmarshalXML(dec, start)
				if err != nil {
					return err
				}
				cc.Criterion = criterion
			case "BidModifier":
				if err := dec.DecodeElement(&cc.BidModifier, &start); err != nil {
					return err
				}
			}
		}
	}
	*ccs = append(*ccs, cc)
	return nil
}
func parseReference(decoder *xml.Decoder, element xml.StartElement) *Reference {
	referenceName := ""
	hintPath := ""
	if ref, ok := getAttrValue(element, "Include"); ok {
		referenceName = ref
	}
LOOP:
	for {
		t, _ := decoder.Token()
		if t == nil {
			break
		}
		switch se := t.(type) {
		case xml.StartElement:
			if se.Name.Local == "HintPath" {
				hintPath = getCharData(decoder)
			}
		case xml.EndElement:
			if se.Name.Local == "Reference" {
				break LOOP
			}
		}
	}
	if referenceName == "" {
		return nil
	}
	sepIndex := strings.Index(referenceName, ",")
	if sepIndex >= 0 {
		referenceName = referenceName[:sepIndex]
	}
	return &Reference{Name: referenceName, Path: hintPath}
}
예제 #23
0
func readPackageoption(attributes []xml.Attr, dec *xml.Decoder) *Packageoption {
	po := &Packageoption{}
	po.ShortDescription = make(map[string]string)

	for _, attribute := range attributes {
		switch attribute.Name.Local {
		case "name":
			po.Name = attribute.Value
		case "default":
			po.Default = attribute.Value == "yes"
		}
	}

forloop:
	for {
		t, err := dec.Token()
		if err != nil {
			break
		}
		switch v := t.(type) {
		case xml.StartElement:
			switch v.Name.Local {
			case "shortdescription":
				lang, text := readShortDescription(v.Attr, dec)
				po.ShortDescription[lang] = text
			}
		case xml.EndElement:
			if v.Name.Local == "packageoption" {
				break forloop
			}
		}
	}
	return po
}
예제 #24
0
파일: xsd.go 프로젝트: rilinor/go-xml
// An <xs:annotation> element may contain zero or more <xs:documentation>
// children.  The xsd package joins the content of these children, separated
// with blank lines.
func (doc *annotation) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	buf := make([][]byte, 1)
	var (
		tok xml.Token
		err error
	)

Loop:
	for {
		tok, err = d.Token()
		if err != nil {
			break
		}

		switch tok := tok.(type) {
		case xml.EndElement:
			break Loop
		case xml.StartElement:
			if (tok.Name != xml.Name{schemaNS, "documentation"}) {
				if err := d.Skip(); err != nil {
					return err
				}
			}
			var frag []byte
			if err := d.DecodeElement(&frag, &tok); err != nil {
				return err
			}
			buf = append(buf, bytes.TrimSpace(frag))
		}
	}
	*doc = annotation(bytes.TrimSpace(bytes.Join(buf, []byte("\n\n"))))
	return err
}
예제 #25
0
func readShortDescription(attributes []xml.Attr, dec *xml.Decoder) (string, string) {
	var lang string
	for _, attribute := range attributes {
		if attribute.Name.Local == "lang" {
			lang = attribute.Value
		}
	}
	var str string
	for {

		t, err := dec.Token()
		if err != nil {
			break
		}
		switch v := t.(type) {
		case xml.CharData:
			str += string(v)
		case xml.EndElement:
			return lang, str
		default:
		}
	}
	// never reached!?!?
	return lang, str
}
예제 #26
0
파일: event.go 프로젝트: ChongFeng/beats
// UnmarshalXML unmarshals UserData XML.
func (u *UserData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	// Assume that UserData has the same general key-value structure as
	// EventData does.
	in := struct {
		Pairs []KeyValue `xml:",any"`
	}{}

	// Read tokens until we find the first StartElement then unmarshal it.
	for {
		t, err := d.Token()
		if err != nil {
			return err
		}

		if se, ok := t.(xml.StartElement); ok {
			err = d.DecodeElement(&in, &se)
			if err != nil {
				return err
			}

			u.Name = se.Name
			u.Pairs = in.Pairs
			d.Skip()
			break
		}
	}

	return nil
}
예제 #27
0
파일: choice.go 프로젝트: voltron42/xtraml
func (c ChoiceParser) ParseList(d *xml.Decoder, start xml.StartElement, containerPtr interface{}, typeofPtr interface{}, appenderType appender) error {
	typeof := reflect.TypeOf(typeofPtr).Elem()
	container := reflect.ValueOf(containerPtr).Elem()
	token, err := d.Token()
	for token != start.End() {
		if err != nil {
			return err
		}
		next, ok := token.(xml.StartElement)
		if ok {
			item, err := c.Parse(d, next)
			if err != nil {
				return err
			}
			val := reflect.ValueOf(item)
			if !val.Type().Implements(typeof) {
				return fmt.Errorf("Item is not a valid %v.", typeof.Name())
			}
			appendFn := appenders[appenderType]
			appendFn(container, val)
		}
		token, err = d.Token()
	}
	return nil
}
예제 #28
0
func extractCombinations(dec *xml.Decoder, terms *[]string) {
	prefix := ""
	emitted := false
	for {
		token, err := dec.Token()
		if err != nil {
			if !emitted && prefix != "" {
				*terms = append(*terms, prefix)
			}
			return
		}
		if _, isEnd := token.(xml.EndElement); isEnd {
			if !emitted && prefix != "" {
				*terms = append(*terms, prefix)
			}
			return
		}
		if start, isStart := token.(xml.StartElement); isStart {
			if start.Name.Local == "indexterm" {
				emitted = true
				if prefix != "" {
					suffix, _ := xmltext(dec)
					*terms = append(*terms, prefix+":"+suffix)
				}
			} else {
				panic("unhandled keyword:" + start.Name.Local)
			}
		}

		if data, isData := token.(xml.CharData); isData {
			prefix = string(data)
		}
	}
}
func (nagc *NegativeAdGroupCriterion) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
	for token, err := dec.Token(); err == nil; token, err = dec.Token() {
		if err != nil {
			return err
		}
		switch start := token.(type) {
		case xml.StartElement:
			tag := start.Name.Local
			switch tag {
			case "adGroupId":
				if err := dec.DecodeElement(&nagc.AdGroupId, &start); err != nil {
					return err
				}
			case "criterionUse":
				if err := dec.DecodeElement(&nagc.CriterionUse, &start); err != nil {
					return err
				}
			case "criterion":
				criterion, err := criterionUnmarshalXML(dec, start)
				if err != nil {
					return err
				}
				nagc.Criterion = criterion
			case "AdGroupCriterion.Type":
				break
			default:
				return fmt.Errorf("unknown NegativeAdGroupCriterion field %s", tag)
			}
		}
	}
	return nil
}
예제 #30
0
파일: grammar.go 프로젝트: katydid/relaxng
func (this *Pair) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	s, err := skipToStart(d)
	if err != nil {
		return err
	}
	this.Left = &NameOrPattern{}
	if err := this.Left.unmarshalXML(d, *s); err != nil {
		return err
	}
	s, err = skipToStart(d)
	if err != nil {
		return err
	}
	this.Right = &NameOrPattern{}
	if err := this.Right.unmarshalXML(d, *s); err != nil {
		return err
	}
	for {
		t, err := d.Token()
		if err != nil {
			return err
		}

		e, ok := t.(xml.EndElement)
		if ok && e.Name.Local == start.Name.Local {
			break
		}
	}
	return nil
}