热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golang学习笔记etree包

关于Etree XML官方文档

etree
The etree package is a lightweight, pure go package that expresses XML in the form of an element tree. Its design was inspired by the Python ElementTree module.

Some of the package's capabilities and features:

Represents XML documents as trees of elements for easy traversal.
Imports, serializes, modifies or creates XML documents from scratch.
Writes and reads XML to/from files, byte slices, strings and io interfaces.
Performs simple or complex searches with lightweight XPath-like query APIs.
Auto-indents XML using spaces or tabs for better readability.
Implemented in pure go; depends only on standard go libraries.
Built on top of the go encoding/xml package.

 

范例1:创建一个XML文档

package main

import (
	"os"
	etree "github.com/beevik/etree"
)

func main() {

	doc := etree.NewDocument()
	doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
	doc.CreateProcInst("xml-stylesheet", `type="text/xsl" href="style.xsl"`)

	people := doc.CreateElement("People")
	people.CreateComment("These are all known people")

	jon := people.CreateElement("Person")
	jon.CreateAttr("name", "Jon")

	sally := people.CreateElement("Person")
	sally.CreateAttr("name", "Sally")

	doc.Indent(2)
	doc.WriteTo(os.Stdout)
}

  

输出:




  
  
  

  

eading an XML file

Suppose you have a file on disk called bookstore.xml containing the following data:


 
  
    
    Giada De Laurentiis
    2005
    30.00
  
 
  
    
    J K. Rowling
    2005
    29.99
  
 
  
    
    James McGovern
    Per Bothner
    Kurt Cagle
    James Linn
    Vaidyanathan Nagarajan
    2003
    49.99
  
 
  
    
    Erik T. Ray
    2003
    39.95
  
 

  

This code reads the file's contents into an etree document.

doc := etree.NewDocument()
if err := doc.ReadFromFile("bookstore.xml"); err != nil {
panic(err)
}

  


You can also read XML from a string, a byte slice, or an io.Reader.

Processing elements and attributes

This example illustrates several ways to access elements and attributes using etree selection queries.

root := doc.SelectElement("bookstore")
fmt.Println("ROOT element:", root.Tag)
 
for _, book := range root.SelectElements("book") {
    fmt.Println("CHILD element:", book.Tag)
    if title := book.SelectElement("title"); title != nil {
        lang := title.SelectAttrValue("lang", "unknown")
        fmt.Printf("  TITLE: %s (%s)\n", title.Text(), lang)
    }
    for _, attr := range book.Attr {
        fmt.Printf("  ATTR: %s=%s\n", attr.Key, attr.Value)
    }
}

  

完整实例:

package main

import (
	"fmt"

	etree "github.com/beevik/etree"
)

func main() {

	doc := etree.NewDocument()
	if err := doc.ReadFromFile("bookstore.xml"); err != nil {
		panic(err)
	}

	root := doc.SelectElement("bookstore")
	fmt.Println("ROOT element:", root.Tag)

	for _, book := range root.SelectElements("book") {
		fmt.Println("CHILD element:", book.Tag)
		if title := book.SelectElement("title"); title != nil {
			lang := title.SelectAttrValue("lang", "unknown")
			fmt.Printf("  TITLE: %s (%s)\n", title.Text(), lang)
		}
		for _, attr := range book.Attr {
			fmt.Printf("  ATTR: %s=%s\n", attr.Key, attr.Value)
		}
	}
}

  输出:

ROOT element: bookstore

CHILD element: book

TITLE: Everyday Italian (en)

ATTR: category=COOKING

CHILD element: book

TITLE: Harry Potter (en)

ATTR: category=CHILDREN

CHILD element: book

TITLE: XQuery Kick Start (en)

ATTR: category=WEB

CHILD element: book

TITLE: Learning XML (en)

ATTR: category=WEB


Path queries
This example uses etree's path functions to select all book titles that fall into the category of 'WEB'. The double-slash prefix in the path causes the search for book elements to occur recursively; book elements may appear at any level of the XML hierarchy.

for _, t := range doc.FindElements("//book[@category='WEB']/title") {
    fmt.Println("Title:", t.Text())
}

 

Output:

Title: XQuery Kick Start
Title: Learning XML

  

 

This example finds the first book element under the root bookstore element and outputs the tag and text of each of its child elements.

for _, e := range doc.FindElements("./bookstore/book[1]/*") {
    fmt.Printf("%s: %s\n", e.Tag, e.Text())
}

 Output:

title: Everyday Italian
author: Giada De Laurentiis
year: 2005
price: 30.00

  

This example finds all books with a price of 49.99 and outputs their titles.

path := etree.MustCompilePath("./bookstore/book[p:price='49.99']/title")
for _, e := range doc.FindElementsPath(path) {
    fmt.Println(e.Text())
}

  

Output:

XQuery Kick Start

  

Note that this example uses the FindElementsPath function, which takes as an argument a pre-compiled path object. Use precompiled paths when you plan to search with the same path more than once.

Other features
These are just a few examples of the things the etree package can do. See the documentation for a complete description of its capabilities.

Contributing
This project accepts contributions. Just fork the repo and submit a pull request!


etree作为一个***在解析XML文件的工具中占据着很重要的地位,它可以查找节点,轮询、生成XML文件。

一、XML的引入写法
在工程中引入XML的方法,建议用第一种

//方法一

xml := `

	
		
		Charles Dickens
	
	
		
		James Joyce
	
`


//方法二

LoginPut= "" +
		" " +
		" " +
		" " +
		" " +
		" %s" +
		" %s" +
		" "

  

 

二、XML的解析

1. 判断所需节点是否存在的方法

方法1:在某个节点范围下查找指定节点是否存在

//whetherExistNode  判断节点是否存在
func whetherExistNode(doc etree.Element, nodeName string) (exist bool) {
	path := etree.MustCompilePath(nodeName)
	bb := doc.FindElementPath(path)
	if bb != nil {
		return true
	} else {
		return false
	}
	return exist
}

  

方法2:获取指定节点的值

//getSpecifiedNodeVal 获取指定节点的值
func getSpecifiedNodeVal(doc etree.Document, nodeName string) (dataSlice []string) {
	path := etree.MustCompilePath(nodeName)
	var val string
	for _, t := range doc.FindElementsPath(path) {
		val = t.Text()
		if len(dataSlice) <= 0 {
			dataSlice = append(dataSlice, val)
		} else {
			repeat := false
			for i := 0; i 

  

方法3:在用SelectElement获取节点值的时候 要判断改节点是否存在,如果不加判断,程序直接就会panic退出,后果会比较严重。

	if tempNode.SelectElement("OperatingSystemVersion") != nil {
		systemVersion = tempNode.SelectElement("OperatingSystemVersion").Text()
		if systemVersion != "" {
			systemType = util.GetOSType(systemVersion)
		}
	} else {
		systemVersion = ""
	}

  

注意点:在用FindElementsPath或FindElements查找节点时建议用FindElementsPath,因为FindElements在查找不到节点时会panic报错,SelectElement和SelectElements,的用法,SelectElements获取到的结果为数组,SelectElement标识选中的单一的节点。

 

	path := etree.MustCompilePath("//PartitionName")
	doc.FindElementsPath(path)

  

重点:1.在获取节点值的时候一定要判断节点是否为空

           2.添加//标识从头开始查找值

           3.doc.SelectElement必须选中开始的父节点,不能跨区域

 

    //FindElementPath  指定父节点查找指定的接点值:节点不存在不会报错
	aa := doc.SelectElement("feed").SelectElement("entry")
	path := etree.MustCompilePath("updatedd")
	cc := aa.FindElementPath(path)
	if cc != nil {
		fmt.Println(cc.Text())
	} else {
		fmt.Println("cc == nil")
	}

  

2.etree支持接口返回内容和XML文件两种解析方式

测试用的data.xml文件


    5134c4aa-8df4-3d41-aafc-927a7546f8b8
    2019-09-25T03:03:29.615Z
    
    
    IBM Power Systems Management Console
    
        323F5D6D-E501-4166-9522-B216B1565862
        
        2019-09-25T03:03:29.914Z
        
        
            IBM Power Systems Management Console
        
        -170243083
 
    
    
        21FE0160-FF83-4852-909B-B7D264E258C8
        
        2019-09-25T03:03:29.916Z
        
        
            IBM Power Systems Management Console
        
        -1052118977
 
    

  

var testData string = `
        21FE0160-FF83-4852-909B-B7D264E258C8
        
        2019-09-25T03:03:29.916Z
        
        
            IBM Power Systems Management Console
        
        -1052118977
    `

 

package main

import (
	"fmt"

	etree "github.com/beevik/etree"
)

var testData string = `
        21FE0160-FF83-4852-909B-B7D264E258C8
        
        2019-09-25T03:03:29.916Z
        
        
            IBM Power Systems Management Console
        
        -1052118977
    `

func main() {

	//读取字符串的方法-----------采用绝对路径的方法
	doc := etree.NewDocument()
	if err := doc.ReadFromString(testData); err != nil {
		panic(err)
	}
	res := doc.FindElement("./entry[0]/id").Text()
	fmt.Println(res)

	// doc := etree.NewDocument()
	// if err := doc.ReadFromFile("data.xml"); err != nil {
	// 	panic(err)
	// }
	// servers := doc.SelectElement("feed")
	// for _, server := range servers.SelectElements("entry") {

	// 	if server.SelectElement("author").SelectElement("name") == nil {
	// 		fmt.Println("测试节点不存在")
	// 	} else {
	// 		fmt.Println(server.SelectElement("author").SelectElement("name").Text())
	// 	}
	// }

}

  输出:

21FE0160-FF83-4852-909B-B7D264E258C8

package main

import (
	"fmt"

	etree "github.com/beevik/etree"
)


func main() {

	doc := etree.NewDocument()
	if err := doc.ReadFromFile("data.xml"); err != nil {
		panic(err)
	}
	servers := doc.SelectElement("feed")
	for _, server := range servers.SelectElements("entry") {

		if server.SelectElement("author").SelectElement("name") == nil {
			fmt.Println("测试节点不存在")
		} else {
			fmt.Println(server.SelectElement("author").SelectElement("name").Text())
		}
	}

}

  输出:

IBM Power Systems Management Console

IBM Power Systems Management Console

 


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
author-avatar
林舒婷880
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有