Тип xml.EndElement
Тип xml.EndElement представляет закрывающий тег XML-элемента в пакете encoding/xml.
Он используется совместно с xml.Decoder при пошаговом (token-based) разборе XML-документов.
Структура содержит поле Name типа xml.Name, которое хранит локальное имя и пространство имен
закрывающего тега. Этот тип возникает, когда декодер встречает закрывающий тег, например, </root>.
Структура
type EndElement struct {
Name Name
}
Где поле Name содержит информацию о имени тега (локальное имя и пространство имен).
Синтаксис
Тип xml.EndElement не имеет собственных методов, он используется как маркер закрывающего тега
при работе с токенами декодера. Обычно его получают через метод Decoder.Token или
Decoder.DecodeElement, проверяя тип токена с помощью утверждения типа.
Пример использования с Decoder.Token
Следующий пример парсит XML-документ, извлекая названия элементов и показывая, когда встречается закрывающий тег:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
func main() {
data := `<book><title>Go Programming</title><author>John Doe</author></book>`
decoder := xml.NewDecoder(strings.NewReader(data))
for {
token, err := decoder.Token()
if err != nil {
break
}
switch elem := token.(type) {
case xml.StartElement:
fmt.Printf("Start: %s\n", elem.Name.Local)
case xml.EndElement:
fmt.Printf("End: %s\n", elem.Name.Local)
case xml.CharData:
// Пропускаем текстовое содержимое
}
}
}
Результат выполнения кода:
"Start: book"
"Start: title"
"End: title"
"Start: author"
"End: author"
"End: book"
В этом примере при встрече закрывающего тега срабатывает ветка xml.EndElement,
и мы печатаем его локальное имя.
Пример проверки соответствия открывающему тегу
Можно использовать xml.EndElement для проверки правильности вложенности,
сравнивая имена открывающего и закрывающего тегов:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
func main() {
data := `<root><item>one</item><item>two</item></root>`
decoder := xml.NewDecoder(strings.NewReader(data))
var lastStart xml.StartElement
for {
token, err := decoder.Token()
if err != nil {
break
}
switch elem := token.(type) {
case xml.StartElement:
lastStart = elem
case xml.EndElement:
if lastStart.Name.Local == elem.Name.Local {
fmt.Printf("Matching pair: <%s>...</%s>\n", elem.Name.Local, elem.Name.Local)
}
}
}
}
Результат выполнения кода:
"Matching pair: <item>...</item>"
"Matching pair: <item>...</item>"
"Matching pair: <root>...</root>"
Здесь мы сохраняем последний открывающий тег и при встрече закрывающего сравниваем их имена.
Пример использования в структуре
Тип xml.EndElement также может использоваться как поле в структуре
при декодировании XML с помощью тегов:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type CustomStruct struct {
End xml.EndElement `xml:"end"`
}
func main() {
data := `<root><end/></root>`
var cs CustomStruct
err := xml.Unmarshal([]byte(data), &cs)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("End element name: %s\n", cs.End.Name.Local)
}
Результат выполнения кода:
"End element name: end"
Обратите внимание, что для успешного разбора тег должен быть самозакрывающимся
(<end/>), так как EndElement соответствует именно закрывающему тегу,
а не открывающему.
Смотрите также
-
тип
xml.StartElement,
который представляет открывающий XML-тег -
тип
xml.Name,
который хранит локальное имя и пространство имен -
тип
xml.Attr,
который представляет атрибут XML-элемента -
тип
xml.CharData,
который представляет текстовое содержимое