XML 验证工具
验证 XML 语法并检查格式错误
XML 输入
什么是 XML 验证?
XML 验证工具用于检查 XML 文档是否符合 XML 1.0 规范(W3C 推荐标准,第五版)定义的结构规则。最基本的检查是确认文档是否格式良好:包含单一根元素、所有标签正确嵌套并已关闭、属性值加有引号,以及保留字符使用了预定义实体。任何不满足上述条件的文档都会导致 XML 解析器抛出错误,而非静默产生错误的输出。
格式良好性(well-formedness)与有效性(validity)的区别至关重要。格式良好的 XML 文档满足 XML 规范本身的语法规则。有效的 XML 文档则更进一步:还需符合外部 schema 定义的约束,例如 DTD(文档类型定义)、XSD(XML Schema 定义)或 Relax NG schema。本工具检查格式良好性,这是最常见也是最基础的验证步骤。缺少这一步,所有后续处理都无从开始。
XML 验证能在问题进入生产环境前提前捕获错误。未关闭的标签、元素名称不匹配、未转义的 & 符号以及重复属性,是手工编辑 XML 时最常见的错误。不同语言的解析器对这些错误的处理方式各异:有的静默失败,有的返回部分结果,有的抛出异常。先将 XML 通过验证器检查可消除这种不确定性,给出明确的通过或失败结果,并提示错误的具体位置。
为什么使用在线 XML 验证工具?
尽早发现 XML 语法错误可防止下游应用程序出现连锁故障。基于浏览器的验证工具无需安装命令行工具或配置 IDE 插件,即可获得即时反馈。
XML 验证工具使用场景
XML 格式良好性规则
XML 1.0 规范定义了一套严格的语法规则。文档必须满足所有这些规则才能被视为格式良好。下表列出了每条规则的内容、要求及正确示例。大多数验证错误都源于其中某条规则。
| 规则 | 要求 | 正确示例 |
|---|---|---|
| Single root element | Document must have exactly one root | <root>...</root> |
| Matched tags | Every opening tag needs a closing tag | <p>text</p> |
| Proper nesting | Tags must close in reverse order of opening | <a><b>...</b></a> |
| Quoted attributes | Attribute values must be in single or double quotes | <el attr="val"/> |
| Entity escaping | Reserved characters must use predefined entities | < > & " ' |
| Case sensitivity | Tag names are case-sensitive: <A> is not </a> | <Book>...</Book> |
| No duplicate attributes | Each attribute name must appear once per element | <el a="1" b="2"/> |
| Valid XML declaration | If present, must be the very first line | <?xml version="1.0"?> |
格式良好 vs DTD 有效 vs Schema 有效
XML 验证分为三个层级。本工具检查第一层(格式良好性),这是另外两层的前提条件。
代码示例
在不同语言中以编程方式验证 XML。每个示例检查格式良好性,若文档格式错误则返回错误信息。
function validateXML(xmlString) {
const parser = new DOMParser()
const doc = parser.parseFromString(xmlString, 'application/xml')
const error = doc.querySelector('parsererror')
if (error) {
return { valid: false, message: error.textContent }
}
return { valid: true, message: 'Well-formed XML' }
}
validateXML('<root><item>hello</item></root>')
// → { valid: true, message: "Well-formed XML" }
validateXML('<root><item>hello</root>')
// → { valid: false, message: "Opening and ending tag mismatch..." }import xml.etree.ElementTree as ET
def validate_xml(xml_string):
try:
ET.fromstring(xml_string)
return True, "Well-formed XML"
except ET.ParseError as e:
return False, str(e)
valid, msg = validate_xml('<root><item>hello</item></root>')
# → (True, "Well-formed XML")
valid, msg = validate_xml('<root><item>hello</root>')
# → (False, "mismatched tag: line 1, column 27")
# With lxml — also supports XSD schema validation
from lxml import etree
schema = etree.XMLSchema(etree.parse('schema.xsd'))
doc = etree.fromstring(b'<root><item>hello</item></root>')
schema.validate(doc) # → True or Falsepackage main
import (
"encoding/xml"
"fmt"
"strings"
)
func validateXML(raw string) error {
decoder := xml.NewDecoder(strings.NewReader(raw))
for {
_, err := decoder.Token()
if err != nil {
if err.Error() == "EOF" {
return nil
}
return err
}
}
}
func main() {
err := validateXML("<root><item>hello</item></root>")
fmt.Println(err) // → <nil>
err = validateXML("<root><item>hello</root>")
fmt.Println(err) // → XML syntax error: unexpected end element </root>
}# Check well-formedness (part of libxml2, pre-installed on macOS/Linux) xmllint --noout document.xml # Exit code 0 = valid, non-zero = errors printed to stderr # Validate against an XSD schema xmllint --noout --schema schema.xsd document.xml # Validate against a DTD xmllint --noout --dtdvalid schema.dtd document.xml # Validate from stdin echo '<root><unclosed>' | xmllint --noout - # → :1: parser error : Premature end of data in tag unclosed line 1