栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

XML中的Schema

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

XML中的Schema

XML中的Schema

对于``Schma`这个词我们可能了解得很少,但其实我们经常会用到,比如在Spring的配置文件中,在SpringMVC的配置文件中,一般我们创建一个Spring的配置文件都会在文件头写一段配置,比如Spring的配置:





然后我们再在其中写我们的bean配置,但此时我们会注意到一个问题,标签里面只能写,等事先规定好的标签,如果写其他的标签的话就会报错,这是为什么呢?

其实这就是Schema的作用。

1. Schema是什么?

XML Schema 的作用是定义 XML 文档的合法构建模块。XML Schema以XML语言为基础,也可以说XML Schema自身就是XML的一种应用。

XML Schema可定义的内容包括:

  • 定义可出现在文档中的元素
  • 定义可出现在文档中的属性
  • 定义哪个元素是子元素
  • 定义子元素的次序
  • 定义子元素的数目
  • 定义元素是否为空,或者是否可包含文本
  • 定义元素和属性的数据类型
  • 定义元素和属性的默认值以及固定值
2. 如何使用? 2.1 创建一个简单的XML文件

user.xml



    jack
    1
    2022-01-01
    jack is a boy!

2.2 创建一个XSD文件

user.xsd,xsd后缀是Schema文件的后缀名称,该文件将定义user.xml文件的格式。




    
        
            
                
                
                
                
            
        
    


2.3 将XML关联XSD文件


    jack
    1
    2022-01-01
    jack is a boy!

在user.xml文件中,我们关联了user.xsd文件,而我们在user.xsd文件中限制了可使用的标签,如果此时我们在user.xml文件中使用其他标签,此时文件就会报错。

3. Sechma中的标签解释 3.1 XSD文件中schema标签的解释




元素是每一个XML Schema的根元素,它可包含以下属性。

# xmlns:xs="http://www.w3.org/2001/XMLSchema"
    显示 schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs:
    
# targetNamespace
	显示在这个xsd文件中定义的标签来自哪一个命名空间,上述我们配置的是http://xuhao.com,一般命名规则为:http://公司域名/xsd文件名
	
# xmlns
	默认的命名规则,一般和targetNamespace相同。
	
# elementFormDefault
	任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。
3.2 XML文件中引用schema标签的解释


    jack
    1
    2022-01-01
    jack is a boy!

# xmlns
	规定了默认命名空间的声明。此声明会告知 schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://xuhao.com" 这个命名空间,和xsd配置的xmln相对应。
	
# xmlns:xsi
	xsi是http://www.w3.org/2001/XMLSchema-instance的别名。表示遵守w3的xml schema规范,xml解析器解析xml文件时,就明白按照什么规范解析了。xml schema规范有很多中,不止w3一家标准。
	
# xsi:schemaLocation
	由一个URI引用对组成,两个URI之间以空白符分隔。第一个URI是名称空间的名字,第二个URI给出xsd文件的位置,模式处理器将从这个位置读取模式文档,该模式文档的目标名称空间必须与第一个URI相匹配。上面的schemaLocation意为:在http://xuhao.com命名空间下的user.xsd文件。
3.3 schema中常见标签解释 3.3.1 annotation

可以包含 appinfo 元素(由应用程序使用的信息)和 documentation 元素(由用户读取或使用的注释或文本)。

3.3.2 restriction

定义一个约束条件。

3.3.3 sequence

规定标签中子元素的顺序。

3.3.4 attribute

规定标签的属性。

3.3.5 simpleType

定义一个简单类型, 用来规定和约束具有纯文本内容的元素(不含子元素即为具有纯文本内容的元素)或属性的值。

使用场景

1. 规定一个元素纯文本部分的类型,或规定一个元素属性的所属类型。 注意是纯文本
2. 当我们对一个元素纯文本的值,元素属性的值需要一些限制的时候。可参考:https://www.w3school.com.cn/schema/schema_elements_ref.asp

用法

规定一个元素纯文本内容的类型:


规定一个元素属性的所属类型:


	
		
	

 

	

我定义了一个worker元素,并规定它具有一个id属性,这个属性的类型为idType,这是我自定义的一个simpleType,这个simpleType中规定了属性值的类型。
当然也可以直接将attribute的type属性设置为xsd:integer,但我这样写是为了让大家更直观的看出simpleType确实可以规定一个元素属性的数据类型。

若父标签是element,则用来约束父标签所定义元素的纯文本内容:


	
		
			
			
		
	

这个simpleType规定了它的父标签所定义的gender元素的纯文本内容是string类型,并且只能取Male和Female两个值,起到了约束的作用。

若父标签是attribute,则用来约束父标签所定义的属性值:


	
		
			
				
					
					
				
			
		
	

这个simpleType规定了它的父标签所定义的person元素的gender属性值是string类型的,且只能取Male和Female两个值。可以想象到spring配置文件中的是否设置为单例的开关的选项就是这样做的。

3.3.6 complexType

定义复杂类型,复杂类型的元素是包含其他元素和/或属性的 XML 元素。

用法


	zhagnsan
    14
    2000-01-01
    未成年


    
        
            
            
            
            
        
        
    

这个complexType为student元素定义了一个复杂类型,这个类型中包含了四个子元素:id,name,gender,addr,并且使用了sequence指示器指定了这四个子元素的顺序,还包含了一个class属性。

simpleType和complexType的区别

simpleType用来定义简单数据类型,其中可以包含对该类型内容的限制,可以指定某属性或元素属于某simpleType,从而起到规定元素文本内容和属性的作用。
complexType定义复杂数据类型,包含复杂的结构,如属性、序列关系(sequence)、选择关系(choice)等等,一般用于定义元素内容,可以指定某元素属于某complexType。

4. 快速生成XSD文件

我们可以使用trang工具来根据xml文件自动生成xsd文件,工具如下。

使用方法:

java -jar trang工具名称 xml文件位置 生成的xsd文件名称

示例

user.xml




    
        jack
        1
        2022-01-01
        jack is a boy!
    

    
        12
    

执行工具(trang-2009111.jar和user.xml都在同一个目录下,生成的user.xsd也在同一个目录)

java -jar .trang-20091111.jar user.xml user.xsd

查看生成的user.xsd



    
    
        
            
                
                
            
            
        
    
    
        
            
                
                
                
                
            
            
        
    
    
    
    
    
        
            
                
            
            
            
        
    
    

可以看到生成的xsd文件基本满足我们的要求,但各别标签的type不是我们想要的,我们可以自行进行更改。

5. 为XSD文件添加注释

有些时候我们在进行xml文件编写时,一些标签会提示该标签是做什么的,如下图:

但我们自己编写的user.xml却没有提示,那么这个功能是怎么做到的呢?

5.1 为标签添加注释

我们可以在xsd的命名空间配置中添加支持注释的命名空间,并在具体的标签中添加注释元素。用例如下:

xmlns:xhtml="http://www.w3.org/1999/xhtml"




    
        
            
                姓名
            
        
    


此时当我们在IDEA中将光标放在标签上时就会出现提示。

6. 解析XML,将XML转换为Java中的数据结构

代码中用到了dom4j,需要导入依赖。


    org.dom4j
    dom4j
    2.1.3

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


public class XmlTransUtil {

    public static List>>> trans(String xml) {
        try {
            Document document = DocumentHelper.parseText(xml);
            Element rootElement = document.getRootElement();
            Iterator iterator = rootElement.elementIterator();
            List>>> resultList = new ArrayList<>();
            // 外层crud
            while (iterator.hasNext()) {
                Element element = iterator.next();
                // 内部标签 pageCode,schema,tablePage,colConfig
                List elementList = element.elements();
                HashMap>> resultMap = new HashMap<>();
                for (Element e : elementList) {
                    List> result = new ArrayList<>();
                    constructedObject(e, result, -1);
                    resultMap.put(e.getName(), result);
                }
                resultList.add(resultMap);
            }
            return resultList;
        } catch (DocumentException e) {
            throw new RuntimeException("XML解析异常");
        }
    }

    private static void constructedObject(Element e, List> result, int level) {
        List elementList = e.elements();
        if (elementList.size() == 0) {
            HashMap fieldMap = new HashMap<>();
            e.attributes().forEach(attr -> fieldMap.put(attr.getName(), attr.getValue()));
            String textTrim = e.getTextTrim();
            fieldMap.put(e.getName(), textTrim);
            result.add(fieldMap);
        }
        Iterator iterator = e.elementIterator();
        while (iterator.hasNext()) {
            Element element = iterator.next();
            if (level == -1) {
                HashMap fieldMap = new HashMap<>();
                String text = element.getTextTrim();
                if (!StringUtils.isEmpty(text)) {
                    fieldMap.put(element.getName(), text);
                }
                element.attributes().forEach(attr -> fieldMap.put(attr.getName(), attr.getValue()));
                result.add(fieldMap);
                if (element.getParent() != null) {
                    HashMap map = result.get(result.size() - 1);
                    Element parent1 = element.getParent();
                    parent1.attributes().forEach(attr -> map.put(attr.getName(), attr.getValue()));
                }
            } else {
                HashMap map = result.get(result.size() - 1);
                String text = element.getText();
                if (!StringUtils.isEmpty(text)) {
                    map.put(element.getName(), text);
                }
                element.attributes().forEach(attr -> map.put(attr.getName(), attr.getValue()));
            }
            if (element.elements().size() > 0) {
                constructedObject(element, result, level + 1);
            }
        }
    }

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993456.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号