package xml

import “encoding/xml”

Package xml implements a simple XML 1.0 parser that understands XML name spaces.

Index 返回首页

Constants Variables type SyntaxError func (e *SyntaxError) Error() string type TagPathError func (e *TagPathError) Error() string type UnsupportedTypeError func (e *UnsupportedTypeError) Error() string type UnmarshalError func (e UnmarshalError) Error() string type CharData func (c CharData) Copy() CharData type Comment func (c Comment) Copy() Comment type Directive func (d Directive) Copy() Directive type ProcInst func (p ProcInst) Copy() ProcInst type Name type Attr type StartElement func (e StartElement) Copy() StartElement func (e StartElement) End() EndElement type EndElement type Token func CopyToken(t Token) Token type Marshaler type Unmarshaler type MarshalerAttr type UnmarshalerAttr func Escape(w io.Writer, s []byte) func EscapeText(w io.Writer, s []byte) error func Marshal(v interface{}) ([]byte, error) func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) func Unmarshal(data []byte, v interface{}) error type Decoder func NewDecoder(r io.Reader) *Decoder func (d *Decoder) Decode(v interface{}) error func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error func (d *Decoder) Token() (t Token, err error) func (d *Decoder) RawToken() (Token, error) func (d *Decoder) Skip() error type Encoder func NewEncoder(w io.Writer) *Encoder func (enc *Encoder) Encode(v interface{}) error func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error func (enc *Encoder) EncodeToken(t Token) error func (enc *Encoder) Flush() error func (enc *Encoder) Indent(prefix, indent string) Examples

返回首页

Encoder MarshalIndent Unmarshal Constants const ( // 适用于本包Marshal输出的一般性XML header // 本常数并不会自动添加到本包的输出里,这里提供主要是出于便利的目的 Header = <?xml version="1.0" encoding="UTF-8"?> + “\n” ) Variables var HTMLAutoClose = htmlAutoClose HTMLAutoClose是应当考虑到自动关闭的HTML元素的集合。

var HTMLEntity = htmlEntity HTMLEntity是标准HTML entity字符到其翻译的映射。

type SyntaxError type SyntaxError struct { Msg string Line int } SyntaxError代表XML输入流的格式错误。

func (*SyntaxError) Error

func (e *SyntaxError) Error() string type TagPathError type TagPathError struct { Struct reflect.Type Field1, Tag1 string Field2, Tag2 string } 反序列化时,如果字段标签的路径有冲突,就会返回TagPathError。

func (*TagPathError) Error

func (e *TagPathError) Error() string type UnsupportedTypeError type UnsupportedTypeError struct { Type reflect.Type } 当序列化时,如果遇到不能转化为XML的类型,就会返回UnsupportedTypeError。

func (*UnsupportedTypeError) Error

func (e *UnsupportedTypeError) Error() string type UnmarshalError type UnmarshalError string UnmarshalError代表反序列化时出现的错误。

func (UnmarshalError) Error

func (e UnmarshalError) Error() string type CharData type CharData []byte CharData类型代表XML字符数据(原始文本),其中XML转义序列已经被它们所代表的字符取代。

func (CharData) Copy

func (c CharData) Copy() CharData type Comment type Comment []byte Comment代表XML注释,格式为,切片中不包含注释标记<!—和–>。

func (Comment) Copy

func (c Comment) Copy() Comment type Directive type Directive []byte Directive代表XML指示,格式为<!directive>,切片中不包含标记<!和>。

func (Directive) Copy

func (d Directive) Copy() Directive type ProcInst type ProcInst struct { Target string Inst []byte } ProcInst代表XML处理指令,格式为

func (ProcInst) Copy

func (p ProcInst) Copy() ProcInst type Name type Name struct { Space, Local string } Name代表一个XML名称(Local字段),并指定名字空间(Space)。Decoder.Token方法返回的Token中,Space标识符是典型的URL而不是被解析的文档里的短前缀。

type Attr type Attr struct { Name Name Value string } Attr代表一个XML元素的一条属性(Name=Value)

type StartElement type StartElement struct { Name Name Attr []Attr } StartElement代表一个XML起始元素。

func (StartElement) Copy

func (e StartElement) Copy() StartElement func (StartElement) End

func (e StartElement) End() EndElement 返回e对应的XML结束元素。

type EndElement type EndElement struct { Name Name } EndElement代表一个XML结束元素。

type Token type Token interface{} Token接口用于保存token类型(CharData、Comment、Directive、ProcInst、StartElement、EndElement)的值。

func CopyToken

func CopyToken(t Token) Token CopyToken返回一个Token的拷贝。

type Marshaler type Marshaler interface { MarshalXML(e *Encoder, start StartElement) error } 实现了Marshaler接口的类型可以将自身序列化为合法的XML元素。

MarshalXML方法将自身调用者编码为零或多个XML元素。 按照惯例,数组或切片会编码为一系列元素,每个成员一条。使用start作为元素标签并不是必须的,但这么做可以帮助Unmarshal方法正确的匹配XML元素和结构体字段。一个常用的策略是在同一个层次里将每个独立的值对应到期望的XML然后使用e.EncodeElement进行编码。另一个常用的策略是重复调用e.EncodeToken来一次一个token的生成XML输出。编码后的token必须组成零或多个XML元素。

type Unmarshaler type Unmarshaler interface { UnmarshalXML(d *Decoder, start StartElement) error } 实现了Unmarshaler接口的类型可以根据自身的XML元素描述反序列化自身。

UnmarshalXML方法解码以start起始单个XML元素。如果它返回了错误,外层Unmarshal的调用将停止执行并返回该错误。UnmarshalXML方法必须正好“消费”一个XML元素。一个常用的策略是使用d.DecodeElement 将XML分别解码到各独立值,然后再将这些值写入UnmarshalXML的调用者。另一个常用的策略是使用d.Token一次一个token的处理XML对象。UnmarshalXML通常不使用d.RawToken。

type MarshalerAttr type MarshalerAttr interface { MarshalXMLAttr(name Name) (Attr, error) } 实现了MarshalerAttr接口的类型可以将自身序列化为合法的XML属性。

MarshalXMLAttr返回一个值为方法调用者编码后的值的XML属性。使用name作为属性的name并非必须的,但这么做可以帮助Unmarshal方法正确的匹配属性和结构体字段。如果MarshalXMLAttr返回一个零值属性Attr{},将不会生成属性输出。MarshalXMLAttr只用于有标签且标签有”attr”选项的结构体字段。

type UnmarshalerAttr type UnmarshalerAttr interface { UnmarshalXMLAttr(attr Attr) error } 实现了UnmarshalerAttr接口的类型可以根据自身的XML属性形式的描述反序列化自身。

UnmarshalXMLAttr解码单个的XML属性。如果它返回一个错误,外层的Umarshal调用会停止执行并返回该错误。UnmarshalXMLAttr只有在结构体字段的标签有”attr”选项时才被使用。

func Escape func Escape(w io.Writer, s []byte) Escape类似EscapeText函数但会忽略返回的错误。本函数是用于保证和Go 1.0的向后兼容。应用于Go 1.1及以后版本的代码请使用EscapeText。

func EscapeText func EscapeText(w io.Writer, s []byte) error EscapeText向w中写入经过适当转义的、有明文s具有相同意义的XML文本。

func Marshal func Marshal(v interface{}) ([]byte, error) Marshal函数返回v的XML编码。

Marshal处理数组或者切片时会序列化每一个元素。Marshal处理指针时,会序列化其指向的值;如果指针为nil,则啥也不输出。Marshal处理接口时,会序列化其内包含的具体类型值,如果接口值为nil,也是不输出。Marshal处理其余类型数据时,会输出一或多个包含数据的XML元素。

XML元素的名字按如下优先顺序获取:

  • 如果数据是结构体,其XMLName字段的标签

  • 类型为xml.Name的XMLName字段的值

  • 数据是某结构体的字段,其标签

  • 数据是某结构体的字段,其字段名

  • 被序列化的类型的名字 一个结构体的XML元素包含该结构体所有导出字段序列化后的元素,有如下例外:

  • XMLName字段,如上所述,会省略

  • 具有标签”-“的字段会省略

  • 具有标签”name,attr”的字段会成为该XML元素的名为name的属性

  • 具有标签”,attr”的字段会成为该XML元素的名为字段名的属性

  • 具有标签”,chardata”的字段会作为字符数据写入,而非XML元素

  • 具有标签”,innerxml”的字段会原样写入,而不会经过正常的序列化过程

  • 具有标签”,comment”的字段作为XML注释写入,而不经过正常的序列化过程,该字段内不能有”–“字符串

  • 标签中包含”omitempty”选项的字段如果为空值会省略 空值为false、0、nil指针、nil接口、长度为0的数组、切片、映射

  • 匿名字段(其标签无效)会被处理为其字段是外层结构体的字段 如果一个字段的标签为”a>b>c”,则元素c将会嵌套进其上层元素a和b中。如果该字段相邻的字段标签指定了同样的上层元素,则会放在同一个XML元素里。

参见MarshalIndent的例子。如果要求Marshal序列化通道、函数或者映射会返回错误。

func MarshalIndent func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) MarshalIndent功能类似Marshal。但每个XML元素会另起一行并缩进,该行以prefix起始,后跟一或多个indent的拷贝(根据嵌套层数)。

Example func Unmarshal func Unmarshal(data []byte, v interface{}) error Unmarshal解析XML编码的数据并将结果存入v指向的值。v只能指向结构体、切片或者和字符串。良好格式化的数据如果不能存入v,会被丢弃。

因为Unmarshal使用reflect包,它只能填写导出字段。本函数好似用大小写敏感的比较来匹配XML元素名和结构体的字段名/标签键名。

Unmarshal函数使用如下规则将XML元素映射到结构体字段上。这些规则中,字段标签指的是结构体字段的标签键’xml’对应的值(参见上面的例子):

  • 如果结构体字段的类型为字符串或者[]byte,且标签为”,innerxml”, Unmarshal函数直接将对应原始XML文本写入该字段,其余规则仍适用。

  • 如果结构体字段类型为xml.Name且名为XMLName,Unmarshal会将元素名写入该字段

  • 如果字段XMLName的标签的格式为”name”或”namespace-URL name”, XML元素必须有给定的名字(以及可选的名字空间),否则Unmarshal会返回错误。

  • 如果XML元素的属性的名字匹配某个标签”,attr”为字段的字段名,或者匹配某个标签为”name,attr” 的字段的标签名,Unmarshal会将该属性的值写入该字段。

  • 如果XML元素包含字符数据,该数据会存入结构体中第一个具有标签”,chardata”的字段中, 该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。

  • 如果XML元素包含注释,该数据会存入结构体中第一个具有标签”,comment”的字段中, 该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。

  • 如果XML元素包含一个子元素,其名称匹配格式为”a”或”a>b>c”的标签的前缀,反序列化会深入 XML结构中寻找具有指定名称的元素,并将最后端的元素映射到该标签所在的结构体字段。 以”>”开始的标签等价于以字段名开始并紧跟着”>” 的标签。

  • 如果XML元素包含一个子元素,其名称匹配某个结构体类型字段的XMLName字段的标签名, 且该结构体字段本身没有显式指定标签名,Unmarshal会将该元素映射到该字段。

  • 如果XML元素的包含一个子元素,其名称匹配够格结构体字段的字段名,且该字段没有任何模式选项 (”,attr”、”,chardata”等),Unmarshal会将该元素映射到该字段。

  • 如果XML元素包含的某个子元素不匹配以上任一条,而存在某个字段其标签为”,any”, Unmarshal会将该元素映射到该字段。

  • 匿名字段被处理为其字段好像位于外层结构体中一样。

  • 标签为”-“的结构体字段永不会被反序列化填写。 Unmarshal函数将XML元素写入string或[]byte时,会将该元素的字符数据串联起来作为值,目标[]byte不能是nil。

Unmarshal函数将属性写入string或[]byte时,会将属性的值以字符串/切片形式写入。

Unmarshal函数将XML元素写入切片时,会将切片扩展并将XML元素的子元素映射入新建的值里。

Unmarshal函数将XML元素/属性写入bool值时,会将对应的字符串转化为布尔值。

Unmarshal函数将XML元素/属性写入整数或浮点数类型时,会将对应的字符串解释为十进制数字。不会检查溢出。

Unmarshal函数将XML元素写入xml.Name类型时,会记录元素的名称。

Unmarshal函数将XML元素写入指针时,会申请一个新值并将XML元素映射入该值。

Example type Decoder type Decoder struct { // Strict默认设为true,强制要求符合XML规范 // 如果设为false,则解析器允许输入中包含常见的错误: // * 如果元素缺少结束标签,解析器会虚构一个结束标签以保证返回值来自良好平衡的Token // * 属性值和字符数据中,未知或畸形的字符entity(以&开始的序列)会丢在一边 // // 设置: // // d.Strict = false // d.AutoClose = HTMLAutoClose // d.Entity = HTMLEntity // // 可以创建一个能处理标准HTML的解析器。 // // Strict模式不会强制要求XML名称空间TR,特别注意它不会拒绝使用未定义前缀的名字空间标签 // 这些标签会将未知前缀作为名字空间URL来记录 Strict bool // 当Strict == false时,AutoClose指定一个元素的集合: // 这些元素在开启后就立刻结束,不管有没有对应关闭标签存在 AutoClose []string // Entity字段用于将非标准的实体名映射到替换的字符串 // parser的行为就好像标准实体映射存在于本字段,即使实际上本字段没有: // // “lt”: “<”, // “gt”: “>”, // “amp”: “&”, // “apos”: “’”, // “quot”: ", Entity map[string]string // CharsetReader字段如果非nil,会定义一个函数来生成转换字符集的io.Reader, // 将给定的非utf-8字符集转换为utf-8字符集。如果CharsetReader字段为nil // 或者返回一个错误,解析将会停止并发挥该错误。CharsetReader的返回值不能都是nil CharsetReader func(charset string, input io.Reader) (io.Reader, error) // DefaultSpace设置未修饰标签的默认名字空间,就好像整个XML流都包装进有个具有属性 // xmlns=”DefaultSpace”的元素内 DefaultSpace string // 内含隐藏或非导出字段 } Decoder代表一个XML解析器,可以读取输入流的部分数据,该解析器假定输入是utf-8编码的。

func NewDecoder

func NewDecoder(r io.Reader) *Decoder 创建一个从r读取XML数据的解析器。如果r未实现io.ByteReader接口,NewDecoder会为其添加缓存。

func (*Decoder) Decode

func (d *Decoder) Decode(v interface{}) error Decode方法功能类似xml.Unmarshal函数,但会从底层读取XML数据并查找StartElement。

func (*Decoder) DecodeElement

func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error DecodeElement方法的功能类似xml.Unmarshal函数,但它会启出一个指向XML起始标签后将解析结果写入v。当客户端自己读取了一些原始XML token但仍想defer调用Unmarshal处理一些元素时很有用。

func (*Decoder) Token

func (d *Decoder) Token() (t Token, err error) Token返回输入流里的下一个XML token。在输入流的结尾处,会返回(nil, io.EOF)

返回的token数据里的[]byte数据引用自解析器内部的缓存,只在下一次调用Token之前有效。如要获取切片的拷贝,调用CopyToken函数或者token的Copy方法。

成功调用的Token方法会将自我闭合的元素(如
)扩展为分离的起始和结束标签。

Token方法会保证它返回的StartElement和EndElement两种token正确的嵌套和匹配:如果本方法遇到了不正确的结束标签,会返回一个错误。

Token方法实现了XML名字空间,细节参见http://www.w3.org/TR/REC-xml-names/。每一个包含在Token里的Name结构体,都会将Space字段设为URL标识(如果可知的话)。如果Token遇到未知的名字空间前缀,它会使用该前缀作为名字空间,而不是报错。

func (*Decoder) RawToken

func (d *Decoder) RawToken() (Token, error) RawToken方法Token方法,但不会验证起始和结束标签,也不将名字空间前缀翻译为它们相应的URL。

func (*Decoder) Skip

func (d *Decoder) Skip() error Skip从底层读取token,直到读取到最近一次读取到的起始标签对应的结束标签。如果读取中遇到别的起始标签会进行迭代,因此可以跳过嵌套结构。如果本方法找到了对应起始标签的结束标签,会返回nil;否则返回一个描述该问题的错误。

type Encoder type Encoder struct { // 内含隐藏或非导出字段 } Encoder向输出流中写入XML数据。

Example func NewEncoder

func NewEncoder(w io.Writer) Encoder NewEncoder创建一个写入w的Encoder。

func (*Encoder) Encode

func (enc *Encoder) Encode(v interface{}) error Encode将v编码为XML后写入底层。参见Marshal函数获取go到XML转换的细节。在返回前enc会调用Flush。

func (*Encoder) EncodeElement

func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error EncodeElement将v的XML编码写入底层, 并使用start作为编码的最外层。参见Marshal函数获取go到XML转换的细节。在返回前enc会调用Flush方法。

func (*Encoder) EncodeToken

func (enc *Encoder) EncodeToken(t Token) error EncodeToken向底层写入一个token。如果StartElement和EndElement的匹配不正确,本方法会返回错误。

EncodeToken 方法不会调用Flush,因为它通常是更大型操作如Encode或EncodeElement方法的一部分(或者用户自定义的Marshaler接口MarshalXML 方法里调用本方法),这些方法会在结束前Flush。调用者创建一个Encoder并直接使用本方法而不使用Encode或EncodeElement方法的话,必须在结束时调用Flush以保证XML数据写入底层的io.Writer接口。

EncodeToken写入ProcInst类型Token时,只允许在底层流最开始写入目标是”xml”的ProcInst。

func (*Encoder) Flush

func (enc *Encoder) Flush() error Flush方法会将缓存中的XML数据写入底层。参见EncodeToken函数获取细节信息。

func (*Encoder) Indent

func (enc *Encoder) Indent(prefix, indent string) Indent函数设定编码器生成XML数据时的格式化缩进信息。细节请参见MarshalIndent函数。

Bugs ☞ XML元素和数据结构体的映射有天生的缺陷:XML元素是依赖顺序的匿名值的集合,而结构体是不依赖顺序的命名值的集合。参见json包获取更适用于数据结构体的文本表示。