Пример #1
0
func ExampleElement_Search() {
	data := `
	  <Staff>
        <Person>
            <FullName>Ira Glass</FullName>
        </Person>
        <Person>
            <FullName>Tom Magliozzi</FullName>
        </Person>
        <Person>
            <FullName>Terry Gross</FullName>
        </Person>
    </Staff>
	`
	root, err := xmltree.Parse([]byte(data))
	if err != nil {
		log.Fatal(err)
	}
	for _, el := range root.Search("", "FullName") {
		fmt.Printf("%s\n", el.Content)
	}

	// Output:
	// Ira Glass
	// Tom Magliozzi
	// Terry Gross
}
Пример #2
0
// Imports reads an XML document containing one or more <schema>
// elements and returns a list of canonical XML name spaces that
// the schema imports or includes, along with a URL for the schema,
// if provided.
func Imports(data []byte) ([]Ref, error) {
	var result []Ref

	root, err := xmltree.Parse(data)
	if err != nil {
		return nil, err
	}

	for _, v := range root.Search(schemaNS, "import") {
		s := Ref{v.Attr("", "namespace"), v.Attr("", "schemaLocation")}
		result = append(result, s)
	}

	var schema []*xmltree.Element
	if (root.Name == xml.Name{schemaNS, "schema"}) {
		schema = []*xmltree.Element{root}
	} else {
		schema = root.Search(schemaNS, "schema")
	}

	for _, tree := range schema {
		ns := tree.Attr("", "targetNamespace")
		for _, v := range tree.Search(schemaNS, "include") {
			s := Ref{ns, v.Attr("", "schemaLocation")}
			result = append(result, s)
		}
	}

	return result, nil
}
Пример #3
0
// Parse reads XML documents containing one or more <schema>
// elements. The returned slice has one Schema for every <schema>
// element in the documents. Parse will not fetch schema used in
// <import> or <include> statements; use the Imports function to
// find any additional schema documents required for a schema.
func Parse(docs ...[]byte) ([]Schema, error) {
	docs = append(docs, StandardSchema...)
	var (
		result = make([]Schema, 0, len(docs))
		schema = make(map[string]*xmltree.Element, len(docs))
		parsed = make(map[string]Schema, len(docs))
		types  = make(map[xml.Name]Type)
	)

	for _, data := range docs {
		var add []*xmltree.Element
		root, err := xmltree.Parse(data)
		if err != nil {
			return nil, err
		}
		if (root.Name == xml.Name{schemaNS, "schema"}) {
			add = []*xmltree.Element{root}
		} else {
			add = root.Search(schemaNS, "schema")
		}

		// We don't explicitly handle <include> declarations.
		// however, by merging documents with the same target
		// namespace together. This saves us some code, but
		// to properly handle <redefine> declarations and
		// schema without target namespaces, we would have to
		// do it another way.
		for _, s := range add {
			ns := s.Attr("", "targetNamespace")
			if v, ok := schema[ns]; !ok {
				schema[ns] = s
			} else {
				s.Children = append(s.Children, v.Children...)
				schema[ns] = s
			}
		}
	}

	for tns, root := range schema {
		s := Schema{TargetNS: tns, Types: make(map[xml.Name]Type)}
		if err := s.parse(root, schema); err != nil {
			return nil, err
		}
		parsed[tns] = s
	}

	for _, s := range parsed {
		for _, t := range s.Types {
			types[XMLName(t)] = t
		}
	}
	for _, s := range parsed {
		if err := s.resolvePartialTypes(types); err != nil {
			return nil, err
		}
		result = append(result, s)
	}
	return result, nil
}
Пример #4
0
func ExampleElement_SearchFunc() {
	data := `
	  <People>
        <Person>
            <FullName>Grace R. Emlin</FullName>
            <Email where="home">
                <Addr>[email protected]</Addr>
            </Email>
            <Email where='work'>
                <Addr>[email protected]</Addr>
            </Email>
        </Person>
        <Person>
            <FullName>Michael P. Thompson</FullName>
            <Email where="home">
                <Addr>[email protected]</Addr>
            </Email>
            <Email where='work'>
                <Addr>[email protected]</Addr>
                <Addr>[email protected]</Addr>
            </Email>
        </Person>
    </People>
	`

	root, err := xmltree.Parse([]byte(data))
	if err != nil {
		log.Fatal(err)
	}

	workEmails := root.SearchFunc(func(el *xmltree.Element) bool {
		return el.Name.Local == "Email" && el.Attr("", "where") == "work"
	})

	for _, el := range workEmails {
		for _, addr := range el.Children {
			fmt.Printf("%s\n", addr.Content)
		}
	}

	// Output:
	// [email protected]
	// [email protected]
	// [email protected]
}
Пример #5
0
func lookupTargetNS(data ...[]byte) []string {
	var result []string
	for _, doc := range data {
		tree, err := xmltree.Parse(doc)
		if err != nil {
			continue
		}
		outer := xmltree.Element{
			Children: []xmltree.Element{*tree},
		}
		elts := outer.Search("http://www.w3.org/2001/XMLSchema", "schema")
		for _, el := range elts {
			ns := el.Attr("", "targetNamespace")
			if ns != "" {
				result = append(result, ns)
			}
		}
	}
	return result
}
Пример #6
0
func ExampleElement_Resolve() {
	data := `
    <collection xmlns:ns="http://ns1.net/">
      <record xmlns:ns="http://ns2.net/">
        <name>Old Town</name>
        <artist xmlns:ns="http://ns3.net/">
          <name>Mustafa Grits</name>
        </artist>
      </record>
      <record xmlns:ns="http://ns4.net/">
        <name>New Town</name>
      </record>
    </collection>
	`
	root, err := xmltree.Parse([]byte(data))
	if err != nil {
		log.Fatal(err)
	}

	// Flatten the tree in depth-first order
	flattened := root.SearchFunc(func(*xmltree.Element) bool { return true })

	fmt.Printf("%s <%s>\n", root.Resolve("ns:foo").Space, root.Name.Local)
	for _, el := range flattened {
		fmt.Printf("%s <%s>\n", el.Resolve("ns:foo").Space, el.Name.Local)
	}

	// Output:
	// http://ns1.net/ <collection>
	// http://ns2.net/ <record>
	// http://ns2.net/ <name>
	// http://ns3.net/ <artist>
	// http://ns3.net/ <name>
	// http://ns4.net/ <record>
	// http://ns4.net/ <name>
}