热门标签 | 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

 


推荐阅读
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 本文全面解析了 Python 中字符串处理的常用操作与技巧。首先介绍了如何通过 `s.strip()`, `s.lstrip()` 和 `s.rstrip()` 方法去除字符串中的空格和特殊符号。接着,详细讲解了字符串复制的方法,包括使用 `sStr1 = sStr2` 进行简单的赋值复制。此外,还探讨了字符串连接、分割、替换等高级操作,并提供了丰富的示例代码,帮助读者深入理解和掌握这些实用技巧。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文将详细介绍Python中*args和**kwargs的用法,包括它们的基本概念、应用场景以及注意事项。 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • 深入解析C语言中结构体的内存对齐机制及其优化方法
    为了提高CPU访问效率,C语言中的结构体成员在内存中遵循特定的对齐规则。本文详细解析了这些对齐机制,并探讨了如何通过合理的布局和编译器选项来优化结构体的内存使用,从而提升程序性能。 ... [详细]
  • 二分查找算法详解与应用分析:本文深入探讨了二分查找算法的实现细节及其在实际问题中的应用。通过定义 `binary_search` 函数,详细介绍了算法的逻辑流程,包括初始化上下界、循环条件以及中间值的计算方法。此外,还讨论了该算法的时间复杂度和空间复杂度,并提供了多个应用场景示例,帮助读者更好地理解和掌握这一高效查找技术。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 本文详细介绍了在CentOS 6.5 64位系统上使用阿里云ECS服务器搭建LAMP环境的具体步骤。首先,通过PuTTY工具实现远程连接至服务器。接着,检查当前系统的磁盘空间使用情况,确保有足够的空间进行后续操作,可使用 `df` 命令进行查看。此外,文章还涵盖了安装和配置Apache、MySQL和PHP的相关步骤,以及常见问题的解决方法,帮助用户顺利完成LAMP环境的搭建。 ... [详细]
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社区 版权所有