First commit
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package xmlcheck
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Validate(source []byte) error {
|
||||
decoder := xml.NewDecoder(bytes.NewReader(source))
|
||||
decoder.CharsetReader = charsetReader
|
||||
decoder.Strict = true
|
||||
depth, roots := 0, 0
|
||||
for {
|
||||
token, err := decoder.Token()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("некорректный XML: %w", err)
|
||||
}
|
||||
switch node := token.(type) {
|
||||
case xml.StartElement:
|
||||
if depth == 0 {
|
||||
roots++
|
||||
if roots > 1 {
|
||||
return fmt.Errorf("найдено более одного корневого XML-элемента")
|
||||
}
|
||||
}
|
||||
depth++
|
||||
case xml.EndElement:
|
||||
depth--
|
||||
case xml.CharData:
|
||||
if depth == 0 && strings.TrimSpace(string(node)) != "" {
|
||||
return fmt.Errorf("текст за пределами корневого XML-элемента")
|
||||
}
|
||||
}
|
||||
}
|
||||
if roots != 1 || depth != 0 {
|
||||
return fmt.Errorf("нет единственного завершённого корневого XML-элемента")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user