如何保证XML正确性

XML是个盒子,什么都能装,但是装进去的东西正确与否恐怕无法得知。往往我们都人工审核、双人复核保证,但是次数多了难免会出错。那么我们如何保证和避免这种问题出现呢?

那就是XSD,当然还有XMLSpy等付费解决方案不在考虑范围内。

JSON也是有Schema的有兴趣可以自行了解下~

DTD & XSD

DTD(Document Type Definition)是一种用于定义XML文档结构的技术。它是一种基于文本的声明,用于定义XML文档的元素、元素的层次结构、属性和实体等规则,从而约束XML文档的合法性

DTD主要用于描述XML文档的结构和约束条件,包括:

  1. 元素声明:定义了XML文档中可能包含的元素,以及元素之间的层次结构和顺序。元素声明指定了元素名称和其内容模型(如子元素的数量和顺序)。

  2. 属性声明DTD允许定义元素可能包含的属性及其数据类型。属性声明指定了属性名称和其数据类型,以及可能的默认值。

  3. 实体声明DTD允许定义实体(entity),用于定义文本片段的缩写或替换。实体可以包含特殊字符、实体引用或外部实体的引用。

  4. CDATA定义:通过CDATA定义,DTD可以指定一段文本内容不进行解析,而直接原样输出。

DTD本身也是一个XML文档,但其语法比XML简单,通常使用文本格式进行定义。DTD定义文件通常以DTD.ent为扩展名。

DTD是一种被广泛使用的XML文档约束技术,在早期XML发展阶段使用非常广泛。它对于简单的XML文档结构定义和验证非常有效,但也存在一些局限性。

XSD(XML Schema Definition)是一种用于定义XML文档结构和内容约束的技术。它是一种基于XML的语言,用于描述XML文档的合法结构和数据类型。XSD定义了XML文档应该包含哪些元素、元素的层次结构、数据类型、默认值等规则,从而允许验证和验证XML文档的有效性

XSD可以用于以下几个方面:

文档结构定义:XSD定义了XML文档的元素、元素的层次结构和顺序,以及元素之间的关系。通过XSD,可以确保XML文档按照指定的结构进行组织和嵌套。

数据类型定义:XSD定义了XML文档中元素和属性的数据类型,例如字符串、整数、日期等。这样可以确保文档中的数据类型符合规定,避免了无效或不一致的数据。

数据约束和验证:XSD可以定义元素和属性的取值范围、长度、枚举值等约束条件。通过这些约束,可以验证XML文档是否符合规定,从而确保数据的有效性和一致性。

文档注释和文档说明:XSD支持添加注释和文档说明,使得XML文档结构和含义更易于理解和维护。

XSD本身也是一个XML文档,使用特定的元素和属性来定义XML文档结构和约束条件。常见的XSD定义元素包括xs:schemaxs:elementxs:complexTypexs:simpleType等。

XSD和DTD的优劣取舍

XSD的使用对于数据交换、数据存储和Web服务等场景非常重要。通过使用XSD,可以定义明确的XML文档结构,帮助开发人员和系统正确解析、生成和验证XML数据。同时,XSD还可以作为文档规范的一部分,促进不同系统之间的数据交换和集成。

DTD(Document Type Definition)和XSD(XML Schema Definition)都是用于定义XML文档结构和约束条件的技术,但它们之间存在一些重要的区别:

  1. 语法:

    • DTD使用一种简单的文本格式来定义XML文档结构和约束条件,其语法相对简单直观,但不够灵活。
    • XSD则是一个基于XML的语言,本身也是一个XML文档,它使用XML的元素和属性来定义XML文档的结构和约束条件,因此语法更加复杂,但也更加灵活和强大。
  2. 功能:

    • DTD的功能相对有限,主要用于描述XML文档的基本结构、元素、属性和实体,它不支持命名空间和数据类型的精确定义。
    • XSD功能更加丰富,它支持命名空间,可以更精确地定义数据类型和数据约束,支持复杂类型的定义,以及更复杂的模式验证和数据处理。
  3. 灵活性:

    • DTD的约束较为简单,不支持复杂数据类型和结构定义,因此其灵活性相对较低。
    • XSD支持更多的数据类型定义、结构定义和约束条件,使得它具有更高的灵活性和扩展性。
  4. 兼容性:

    • DTDXML早期定义技术,由于其简单性和广泛应用,它仍然被许多遗留系统和早期XML文档所使用,具有一定的兼容性优势。
    • XSDXML Schema的标准规范,它在功能上更为强大和灵活,但可能不被一些早期的XML处理程序所支持。

总体而言,如果需要简单的XML文档结构定义和验证,或者对于兼容性要求较高的情况,可以选择使用DTD。而如果需要更复杂和精确的XML文档约束,以及更好的灵活性和扩展性,XSD则是更好的选择。随着XML技术的发展,XSD逐渐成为主流的XML文档约束技术,并取代了DTD在许多场景的应用。

使用 XSD.exe 对 XML 文件生成 XSD 架构文件

XML 架构定义工具 (XSD.exe) 通常可在以下路径中找到:C:\Program Files (x86)\Microsoft SDKs\Windows\{version}\bin\NETFX {version} Tools\

GrayControlConfig配置文件举例

<GrayControlConfig XMLns:xsi="http://www.w3.org/2001/XMLSchema-instance" XMLns:XSD="http://www.w3.org/2001/XMLSchema">
<GrayControls>
<GrayControlConfigItem Name="ProfileConsumerByOpenApp" EnableGrayControl="1" EnableAllowTenantIds="true" EnableAllowAllTenant="false">
<AllowTenantIds>
<AllowTenantId>100001</AllowTenantId>
</AllowTenantIds>
</GrayControlConfigItem>
<GrayControlConfigItem Name="StaffAndOrgSubPath" EnableGrayControl="false" EnableAllowTenantIds="true" EnableBlockTenantIds="false" EnableAllowTenantIdStartNum="false" EnableAllowAllTenant="false" EnableGrayMultiWrite="true">
<AllowTenantIds>
<AllowTenantId>-1</AllowTenantId>
</AllowTenantIds>
</GrayControlConfigItem>
</GrayControls>
</GrayControlConfig>

下面的命令从GrayControlConfig.xml生成一个XSD架构文件

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.50
** Copyright (c) 2017 Microsoft Corporation
********************************************************************** C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>xsd.exe D:\GrayControlConfig.xml /outputdir:D:\
Microsoft(R) Xml 架构/数据类型支持实用工具
[Microsoft (R) .NET Framework, Version 4.8.3928.0]
Copyright (C) Microsoft Corporation. All rights reserved.
正在写入文件“D:\GrayControlConfig.xsd”。 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>

可以看到生成的XSD文件如下,但是AllowTenantId我们预期是数字类型,我们可以手动改一下。

<?XML version="1.0" encoding="utf-8"?>
<xs:schema id="GrayControlConfig" XMLns="" XMLns:xs="http://www.w3.org/2001/XMLSchema" XMLns:msdata="urn:schemas-microsoft-com:XML-msdata">
<xs:element name="GrayControlConfig" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="GrayControls">
<xs:complexType>
<xs:sequence>
<xs:element name="GrayControlConfigItem" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="AllowTenantIds" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="AllowTenantId" type="xs:string 改成 XSD:unsignedInt" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Name" type="xs:string" />
<xs:attribute name="EnableGrayControl" type="xs:string" />
<xs:attribute name="EnableAllowTenantIds" type="xs:string" />
<xs:attribute name="EnableAllowAllTenant" type="xs:string" />
<xs:attribute name="EnableBlockTenantIds" type="xs:string" />
<xs:attribute name="EnableAllowTenantIdStartNum" type="xs:string" />
<xs:attribute name="EnableGrayMultiWrite" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

Visual Studio 外部工具调用 XSD.exe

使用VS的外部工具,工具 -> 外部工具 -> 添加

  • 标题:XSD(任意即可)
  • 命令:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools
  • 参数:$(ItemFileName)$(ItemExt)
  • 初始目录:$(ItemDir)
  • 使用输出窗口:(可选,方便调试)
  • 提示输入参数:(可选,方便调试可以看到具体参数)

在解决方案中选中一个XML文件,然后选择工具->XSD,就会生成一个XSD文件,他会生成在选中文件同目录中。此时选择显示所有文件然后包含在内即可。

输出窗口的日志

Microsoft(R) xml 架构/数据类型支持实用工具
[Microsoft (R) .NET Framework, Version 2.0.50727.3038]
Copyright (C) Microsoft Corporation. All rights reserved.
正在写入文件“D:\Source\XXX\Configuration\Configuration\Configuration\Account_Common\GrayControlConfig.xsd”。

如何验证XML?

Visual Studio XML工具

在解决方案中打开一个XML文件,然后选择XML->创建架构,就会生成一个XSD文件,他会生成XSD文件,文件会在C:\Users\XXX\AppData\Local\Temp\XX.xsd中。可以手工将其复制到项目中。

选择XML菜单点击架构选项,点击添加选择我们刚才生成的xsd文件,

文件VS会自动去验证XSD文件,如果XSD文件有错误,会在XML文件中显示错误信息。

自定义 GUID 类型验证

AppId是一个GUID的字符串,但是我们如何保证他是标准的00000000-0000-0000-0000-000000000000标准格式呢?

<SystemManageMapping majorVersion="1" minorVersion="141">
<Applications>
<Application AppId="2EC95F56-8331-4CA9-9423-1FABCE30D653" AppName="APP1" AppType="6" ProductId="CCBAAACA-B8F7-404E-B626-C02006EEEF40" ProductName="APP1" Chinese="应用1"/>
<Application AppId="15E6E58A-5965-459E-BF55" AppName="APP2" AppType="4" ProductId="" ProductName="APP2" Chinese="应用2"/>
</Applications>
</SystemManageMapping>

自定义XSD simpleType类型,使用正则去验证它,当然还有其余各种类型,我们只是用GUID举个例子

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/xmlSchema">
<xs:element name="SystemManageMapping">
<xs:complexType>
<xs:sequence>
<xs:element name="Applications">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Application">
<xs:complexType>
<xs:attribute name="AppId" type="GUID" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="GUID">
<xs:restriction base="xs:string">
<xs:pattern value="([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})|(\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\})"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

可以看到验证器成功的验证了数据类型。

使用代码验证

使用 Linq to XML XmlSchemaSet 去验证


internal class Program
{
private static void Main(string[] args)
{
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", $"{Environment.CurrentDirectory}/Account_Common/GrayControlConfig.xsd");
Console.WriteLine("Attempting to validate");
XDocument custOrdDoc = XDocument.Load($"{Environment.CurrentDirectory}/Account_Common/GrayControlConfig.xml"); bool isError = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
isError = true;
ErrorLog(e.Message);
}); if (isError)
DebugLog("Error end");
else
DebugLog("Success end", ConsoleColor.Green); Console.ReadKey();
} internal static void DebugLog(string msg, ConsoleColor color = ConsoleColor.Yellow)
{
ConsoleColor currentColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(msg);
Console.ForegroundColor = currentColor;
} internal static void ErrorLog(string msg)
{
ConsoleColor currentColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg);
Console.ForegroundColor = currentColor;
}
}

可以看到输出日志中AllowTenantId字段无法通过验证

Attempting to validate
“AllowTenantId”元素无效 - 根据数据类型“http://www.w3.org/2001/XMLSchema:int”,值“-1fff”无效 - 字符串“-1fff”不是有效的 Int32 值。
Error end

参考

如何保证XML正确性的更多相关文章

  1. XML的验证模式

    XML文件的验证模式保证了XML文件的正确性,而比较常用的验证模式有两种:DTD和XSD. DTD与XSD区别 DTD(Document Type Definition)即文档类型定义,是一种XML约 ...

  2. python用ElemenTree快速高效的解析xml

    python解析xml有很多种方法,比较流行的由SAX,DOM和ElementTree,简要介绍一下这几种方法的异同: 方法 特点 SAX SAX解析通过流模式在解析XML的过程中触发对应的事件(st ...

  3. json转xml报[java.lang.NoClassDefFoundError: nu/xom/Serializer]

    原文:http://blog.csdn.net/figo645/article/details/48413571 开始学习JSON了,那么很自然的,我开始要熟悉一些基本的JSON语法 {}代表对象,[ ...

  4. XML知识总结

    1.XML概念及作用? XML( eXtensible Markup Language,可扩展标记语言)是一种简单的数据存储语言 作用:用来存储和交换数据 无法描述页面的排版和显示形式 2.XML和X ...

  5. 【spring】spring源码阅读之xml读取、bean注入(BeanFactory)

    前言 此源码其实是在4月中旬就看了,而且当初也写了一份word文档,但不打算直接把word发上来.还是跟着以前的笔记.跟踪代码边看边写吧. 其实当初看源码的理由很简单,1.才进新公司,比较有空闲.2. ...

  6. Spring注解配置和xml配置优缺点比较

    Spring注解配置和xml配置优缺点比较 编辑 ​ 在昨天发布的文章<spring boot基于注解方式配置datasource>一文中凯哥简单的对xml配置和注解配置进行了比较.然后朋 ...

  7. 死磕Spring之IoC篇 - BeanDefinition 的加载阶段(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  8. 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  9. XML 基础

    linux下xml编辑器 vim gedit editix wonderful;免费30天;可以进行有效性检查 xerces oxygen 收费 xmlcopyedit serna free 是ser ...

  10. TCP 三次握手四次挥手, ack 报文的大小.tcp和udp的不同之处、tcp如何保证可靠的、tcp滑动窗口解释

    一.TCP三次握手和四次挥手,ACK报文的大小 首先连接需要三次握手,释放连接需要四次挥手 然后看一下连接的具体请求: [注意]中断连接端可以是Client端,也可以是Server端. [注意] 在T ...

随机推荐

  1. 各种SQL连接符Join

    一.连接符分类,内连接,外连接 1.内连接:Inner Join简写Join. 2.外连接:Left Outer Join 简写Left Join:Right Outer Join 简写Right J ...

  2. [NSSCTF 2022 Spring Recruit]babyphp

    打开靶机,先看了一遍代码,发现要拿到flag,就必须先满足三个条件,即分别为a,b,c 第一层:需要a满足条件 isset($_POST['a'])&&!preg_match('/[0 ...

  3. Pinely Round 2 (Div. 1 + Div. 2) (CF1863)

    本来开了某场远古 Div 1,然后学了一堆前置知识至今仍然不会 E.换一场写来得及吗? A. Channel 模拟,略. B. Split Sort Description 给你一个长度为 \(n\) ...

  4. Java模块化应用实践之精简JRE(内含开源)

    导语 Java9及以后的版本引入了模块化特性,但是直到今天JDK21都发布了,依然没有被大量使用起来,那么这个特性就真的没啥意义了吗? 别忘了,Java本身可是把模块化做到了极致的,所以可以利用这个特 ...

  5. 接口开放太麻烦?试试阿里云API网关吧

    前言 我在多方合作时,系统间的交互是怎么做的?这篇文章中写过一些多方合作时接口的调用规则和例子,然而,接口开放所涉及的安全.权限.监控.流量控制等问题,可不是简简单单就可以解决的,这一般需要专业的开放 ...

  6. Java之对象内存分析

    相信大家有时候在读代码的时候应该都会有以下情况: 这个对象本定义在上面,乱跑什么?怎么又到下面去了? 欸?我明明改变了这个对象的值,怎么没变呢? 要想搞清楚某一对象在程序中是怎样活蹦乱跳的,首先我们要 ...

  7. npm 发布包时 图片打包在新的项目引入不显示 路径错误解决方案

    使用的是vue-cli 4.0以上脚手架 vue2.6 封装好组件后 npm publish ,在其他项目引入该组件库 图片显示失败 打开F12时看到 组件库里图片是/img/图片名,可是该项目没有此 ...

  8. DataGrip安装与使用

    写在前面:同学们记得以命令为主,图形界面为辅.了解图形怎么操作即可 一.DataGrip软件的安装和初始化 首先在浏览器上搜索datagrip,然后打开连接 点击DOWNLOAD   按照你电脑系统来 ...

  9. 一文搞懂C#中类成员的可访问性

    公众号「DotNet学习交流」,分享学习DotNet的点滴. 文末有总结,想快速浏览的朋友可直接看文末. 1.成员访问修饰符 在C#中类成员访问修饰符一共有5个,分别是public.private.p ...

  10. SQL 语言标准简介

    版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 一.简介 结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是 ...