您的位置:首页 > 其它

XML Schema学习笔记

2017-03-30 20:59 330 查看

一、简介

  XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。

XML Schema:

定义可出现在文档中的元素
定义可出现在文档中的属性
定义哪个元素是子元素
定义子元素的次序
定义子元素的数目
定义元素是否为空,或者是否可包含文本
定义元素和属性的数据类型
定义元素和属性的默认值以及固定值

XML Schema 使用 XML 语法,因此有很多好处:

不必学习新的语言,了解XML即可
可使用 XML 编辑器来编辑 Schema 文件
可使用 XML 解析器来解析 Schema 文件
可通过 XML DOM 来处理 Schema
可通过 XSLT 来转换 Schema
如果对XML的命名空间不理解的可参考:XML学习笔记

XML Schema 参考手册

1.1 XSD - <schema> 元素

  <schema> 元素是每一个 XML Schema 的根元素:

<?xml version="1.0"?>
<xs:schema>
...
</xs:schema>
  <schema> 元素可包含属性。一个 schema 声明往往看上去类似这样:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
...
</xs:schema>
上面代码解释:

xmlns:xs="http://www.w3.org/2001/XMLSchema"
  显示 schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs:
targetNamespace="http://www.w3school.com.cn"
  显示被此 schema 定义的元素来自命名空间: "http://www.w3school.com.cn"。
xmlns="http://www.w3school.com.cn"
  指出默认的命名空间是 "http://www.w3school.com.cn"。
elementFormDefault="qualified"
  指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。

1.2 在 XML 文档中引用 Schema

<?xml version="1.0"?>
<note xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
...
</note>
  其中note只是这个XML文件的根元素。

上面代码解释:

xmlns="http://www.w3school.com.cn"
  规定了默认命名空间的声明。此声明会告知 schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://www.w3school.com.cn" 这个命名空间。

  一旦您拥有了可用的 XML Schema 实例命名空间:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  您就可以使用 schemaLocation 属性了。此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的 XML schema 的位置:
xsi:schemaLocation="http://www.w3school.com.cn note.xsd"


  XML和Schema的命名空间标签使用格式是相同的(这也是Schema相对与DTD的优势),但XML和Schema都有各自的独特的属性,这也是由他们不同的功能决定的,Schema主要给XML提供服务,所以会规定好targetNameSpace来声明命名空间的名字,而XML需要使用schema的服务,所以需要SchemaLocation来声明使用的命名空间。

二、Schema深入之简单的类型

XML Schema 拥有很多内建的数据类型:

xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time

2.1 XSD 简易元素

  XML Schema 可定义 XML 文件的元素。简易元素指那些只包含文本的元素,它不会包含任何其他的元素或属性。

定义简易元素的语法:

<xs:element name="xxx" type="yyy"/>
  此处 xxx 指元素的名称,yyy 指元素的数据类型。

  简易元素也可以设置默认值和固定值,通过default属性指定默认值,使用fixed属性指定固定值,示例如下:

简易元素定义:

<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>
对应的XML 元素使用示例:
<lastname>Smith</lastname>
<age>28</age>
<dateborn>1980-03-27</dateborn>


2.2 XSD 属性

  简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。

定义属性的语法是:

<xs:attribute name="xxx" type="yyy"/>
  在此处,xxx 指属性名称,yyy 则规定属性的数据类型。

  同样属性也可以设置默认值和固定值,通过default属性指定默认值,使用fixed属性指定固定值

  在缺省的情况下,属性是可选的。如需规定属性为必选,我们需要使用 "use" 属性

<xs:attribute name="lang" type="xs:string" use="required"/>


2.3 XSD 限定 / Facets

  当 XML 元素或属性拥有被定义的数据类型时,就会向元素或属性的内容添加限定。假如 XML 元素的类型是 "xs:date",而其包含的内容是类似 "Hello World" 的字符串,元素将不会(通过)验证。这是对简易元素/属性的基本限定。

  限定(restriction)用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet。

  如果使用限定,那么气type(类型)属性就不能使用内建的数据类型,这个时候我们就需要使用自定义类型了,其形式如下:

<xs:element name="...">
<xs:simpleType>
...
</xs:simpleType>
</xs:element>
但是有时候也会遇到下面的形式:

<xs:element name="..." type="typeName">
<xs:simpleType name="typeName">
...
</xs:simpleType>
</xs:element>
  有什么区别吗?第一种形式中xs:element中没有指定type类型,因为它默认使用的就是其内部定义的类型。然而xs:simpleType并不是当前定义元素的组成部分,换句话说,其可以被其它xs:element所使用。这样只需要在xs:element标签的属性type中指定这个xs:simpleType的name值即可,这也就是第二种形式。

  然后使用restriction 元素定义对simpleType等元素进行定义约束,restriction元素包含一个必选属性base,该属性规定在该 schema(或由指定的命名空间指示的其他 schema)中定义的内建数据类型、simpleType 或 complexType 元素的名称。形式如下:

<xs:element name="...">
<xs:simpleType>
<xs:restriction base="...">
...
</xs:restriction>
</xs:simpleType>
</xs:element>


restriction语法如下:

<restriction id=ID base=QName any attributes >

Content for simpleType:
(annotation),(simpleType),(minExclusive|minInclusive|
maxExclusive|maxInclusive|totalDigits|fractionDigits|
length|minLength|maxLength|enumeration|whiteSpace|pattern)*))

Content for simpleContent:
(annotation),(simpleType),(minExclusive |minInclusive|
maxExclusive|maxInclusive|totalDigits|fractionDigits|
length|minLength|maxLength|enumeration|whiteSpace|pattern)*)?,
((attribute|attributeGroup)*,anyAttribute?))

Content for complexContent:
(annotation?,(group|all|choice|sequence)?,
((attribute|attributeGroup)*,anyAttribute?))

</restriction>




2.3.1 对值的限定(minInclusive&maxInclusive)

下面的例子定义了带有一个限定且名为 "age" 的元素。age 的值不能低于 0 或者高于 120:

<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>


2.3.2 对一组值的限定(enumeration)

如需把 XML 元素的内容限制为一组可接受的值,我们要使用枚举约束(enumeration constraint)。

下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi, Golf, BMW:

<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>


2.3.3 对一系列值的限定(pattern)

如需把 XML 元素的内容限制定义为一系列可使用的数字或字母,我们要使用模式约束(pattern constraint)。

下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值只有小写字母 a - z 其中的一个:

<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
注:如果您对正则表达式有所了解,name对value值就不会感到陌生。正则表达式可不止只是上面的这一个功能,更多详细正则表达式功能在此不详细叙述。关于pattern的一些示例可以参考:http://www.w3school.com.cn/schema/schema_facets.asp

2.3.4 对空白字符的限定(whiteSpace)

如需规定对空白字符(whitespace characters)的处理方式,我们需要使用 whiteSpace 限定。

下面的例子定义了带有一个限定的名为 "address" 的元素。whiteSpace 限定的值包含如下几个:

replace:意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符)
collapse:这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格)

preserve:意味着 XML 处理器不会移除任何空白字符:

<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:element>


2.3.5 对长度的限定(length&minLength&maxLength)

如需限制元素中值的长度,我们需要使用 length、maxLength 以及 minLength 限定。

本例定义了带有一个限定且名为 "password" 的元素。其值必须精确到 8 个字符:

<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义了带有一个限定的名为 "password" 的元素。其值最小为 5 个字符,最大为 8 个字符:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="5"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>


三、Schema深入之复杂的类型

  复合元素是指包含其他元素及/或属性的 XML 元素,其包含有四种类型的复合元素:

空元素
包含其他元素的元素
仅包含文本的元素
包含元素和文本的元素

注释:上述元素均可包含属性!

  在 XML Schema 中,我们有两种方式来定义复合元素,下面以这个XML来进行举例:

<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
<1> 通过命名此元素,可直接对"employee"元素进行声明

<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
  假如您使用上面所描述的方法,那么仅有 "employee" 可使用所规定的复合类型。请注意其子元素,"firstname" 以及 "lastname",被包围在指示器 <sequence>中。这意味着子元素必须以它们被声明的次序出现。(指示器会在下面进行详细介绍)
<2> "employee" 元素可以使用 type 属性

  其实我们在上面已经提及了这部分,type属性的作用是引用要使用的复合类型的名称:

<xs:element name="employee" type="personinfo"/>

<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
  这样做的好处是任何xs:element定义的时候都可以引用name="personinfo"的这个xs:complexType。

  我们也可以在已有的复合元素之上以某个复合元素为基础,然后添加一些元素,这非常像平常说的继承关系,就像这样:
<xs:element name="employee" type="fullpersoninfo"/>

<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
  其中<xs:extension base="personinfo"></xs:sequence>就是将此元素定位基础。

3.1 XSD 复合空元素

  空的复合元素不能包含内容,只能含有属性。下面是一个空的 XML 元素:

<product prodid="1345" />
  在Schema中声明此 "product" 元素如下:

<xs:element name="product">
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
</xs:element>
  或者您可以为一个 complexType 元素起一个名字,然后为 "product" 元素设置一个 type 属性并引用这个 complexType 名称(通过使用此方法,若干个元素均可引用相同的复合类型):
<xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>


3.2 XSD 复合类型 - 仅含元素

  XML 元素,"person",仅包含其他的元素:

<person>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>
  我们可以在 schema 中这样定义 "person" 元素:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
注意:其中使用了指示器,这意味着被定义的元素必须按上面的次序出现在 "person" 元素中。我们也可以为 complexType 元素设定一个名称,并让 "person" 元素的 type 属性来引用此名称,与上面类同,就不在举例了。

3.3 XSD 仅含文本复合元素

  仅含文本的复合元素可包含文本和属性。

  此类型仅包含简易的内容(文本和属性),因此我们要向此内容添加 simpleContent 元素。当使用简易内容时,我们就必须在 simpleContent 元素内定义扩展或限定,就像这样:

<xs:element name="某个名称">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="basetype">
....
....
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
或者:
<xs:element name="某个名称">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="basetype">
....
....
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
注意:需要使用 extension 或 restriction 元素来扩展或限制元素的基本简易类型。

示例如下:

  这里有一个 XML 元素的例子,"shoesize",其中仅包含文本:

<shoesize country="france">35</shoesize>
  下面这个例子声明了一个复合类型,其内容被定义为整数值,并且 "shoesize" 元素含有名为 "country" 的属性:
<xs:element name="shoesize">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
  我们也可为 complexType 元素设定一个名称,并让 "shoesize" 元素的 type 属性来引用此名称(通过使用此方法,若干元素均可引用相同的复合类型):
<xs:element name="shoesize" type="shoetype"/>
<xs:complexType name="shoetype">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>


3.4 XSD 带有混合内容的复合类型

  混合的复合类型可包含属性、元素以及文本。详见:http://www.w3school.com.cn/schema/schema_complex_mixed.asp

3.5 XSD 复合类型指示器

  通过指示器,我们可以控制在文档中使用元素的方式。有七种指示器:

Order 指示器:
All
Choice
Sequence

Occurrence 指示器:
maxOccurs
minOccurs

Group 指示器:
Group name
attributeGroup name

3.5.1 Order 指示器

  Order 指示器用于定义元素的顺序。
<1> All 指示器

  <all> 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次:

<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>


注:当使用 <all> 指示器时,你可以把 <minOccurs> 设置为 0 或者 1,而只能把 <maxOccurs> 指示器设置为 1

<2> Choice 指示器

  <choice> 指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼):

<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>


提示:如需设置子元素出现任意次数,可将 <maxOccurs> 设置为 unbounded(无限次)。
<3> Sequence 指示器

  <sequence> 规定子元素必须按照特定的顺序出现:

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>


3.5.2 Occurrence 指示器

  Occurrence 指示器用于定义某个元素出现的频率。

注:对于所有的 "Order" 和 "Group" 指示器(any、all、choice、sequence、group name 以及 group reference),其中的 maxOccurs 以及 minOccurs 的默认值均为 1。
<1> maxOccurs 指示器

  <maxOccurs> 指示器可规定某个元素可出现的最大次数:

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
  上面的例子表明,子元素 "child_name" 可在 "person" 元素中最少出现一次(其中 minOccurs 的默认值是 1),最多出现 10 次。
<2> minOccurs 指示器

  <minOccurs> 指示器可规定某个元素能够出现的最小次数:

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
  上面的例子表明,子元素 "child_name" 可在 "person" 元素中出现最少 0 次,最多出现 10 次。

提示:如需使某个元素的出现次数不受限制,请使用 maxOccurs="unbounded" 这个声明。

3.5.3 Group 指示器

  Group 指示器用于定义相关的数批元素。

<1> 元素组

  元素组通过 group 声明进行定义:

<xs:group name="组名称">
...
</xs:group>
  您必须在 group 声明内部定义一个 all、choice 或者 sequence 元素。下面这个例子定义了名为 "persongroup" 的 group,它定义了必须按照精确的顺序出现的一组元素:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
将 group 定义完毕以后,就可以在另一个定义中引用它了:

<xs:element name="person" type="personinfo"/>

<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<2> 属性组

  属性组通过 attributeGroup 声明来进行定义:
<xs:attributeGroup name="组名称">
...
</xs:attributeGroup>
下面这个例子定义了名为 "personattrgroup" 的一个属性组:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
已定义完毕属性组之后,就可以在另一个定义中引用它了,就像这样:
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>


3.6 XSD <any> 元素

  <any> 元素使我们有能力通过未被 schema 规定的元素来拓展 XML 文档!换句话说,我们用<any>元素进行占位,然后就可以使用任意元素进行插入了,也就是说我们想拓展原来的元素,只需要在其位置插入<any>元素,然后在其它地方定义即可,这样既不会破坏原来的结构,也进行了相应的拓展。

详细参见:http://www.w3school.com.cn/schema/schema_complex_any.asp

3.7 XSD <anyAttribute> 元素

  <anyAttribute> 元素使我们有能力通过未被 schema 规定的属性来扩展 XML 文档!

  与上面的Any类同,只不过是一个拓展的是元素,一个拓展的是属性。

详细参见:http://www.w3school.com.cn/schema/schema_complex_anyattribute.asp

注:<any> 和 <anyAttribute> 均可用于制作可扩展的文档!它们使文档有能力包含未在主 XML schema 中声明过的附加元素。

3.8 XSD 元素替换(Element Substitution)

  通过 XML Schema,一个元素可对另一个元素进行替换。

详细参见:http://www.w3school.com.cn/schema/schema_complex_subst.asp

w3cschool提供的XSD 实例:http://www.w3school.com.cn/schema/schema_example.asp

四、Schema深入之数据类型

4.1 字符串

  字符串数据类型用于可包含字符串的值。字符串数据类型可包含字符、换行、回车以及制表符。

注:如果您使用字符串数据类型,XML 处理器就不会更改其中的值。

scheme 中字符串声明的例子:

<xs:element name="customer" type="xs:string"/>
  规格化字符串数据类型(NormalizedString Data Type):规格化字符串数据类型同样可包含字符,但是 XML 处理器会移除折行,回车以及制表符。

schema 中规格化字符串数据类型的例子:
<xs:element name="customer" type="xs:normalizedString"/>
  Token 数据类型(Token Data Type):Token 数据类型同样可包含字符,但是 XML 处理器会移除换行符、回车、制表符、开头和结尾的空格以及(连续的)空格。

schema 中有关 token 声明的例子:
<xs:element name="customer" type="xs:token"/>
  字符串数据类型:请注意,所有以下的数据类型均衍生于字符串数据类型(除了字符串数据类型本身)!



对字符串数据类型的限定(Restriction)

可与字符串数据类型一同使用的限定:

enumeration
length
maxLength
minLength
pattern (NMTOKENS、IDREFS 以及 ENTITIES 无法使用此约束)
whiteSpace

4.2 日期及时间数据类型(Date and Time Data Types)

详见:http://www.w3school.com.cn/schema/schema_dtypes_date.asp

4.3 数值类型

详见:http://www.w3school.com.cn/schema/schema_dtypes_numeric.asp

4.4 杂项数据类型(Miscellaneous Data Types)

其他杂项数据类型包括逻辑、base64Binary、十六进制、浮点、双精度、anyURI、anyURI 以及 NOTATION。

详见:http://www.w3school.com.cn/schema/schema_dtypes_misc.asp

  

待参考资料:

XML和Schema命名空间详解

最后修改时间:2017年3月31日20:53:29

********************************************************************************结束语********************************************************************************************

  我在写这篇博客的时候也是一名初学者,有任何疑问或问题请留言,或发邮件也可以,邮箱为:fanxiaobin.fxb@qq.com,我会尽早的进行更正及更改。

在我写过的博客中有两篇博客是对资源的整理,可能对大家都有帮助,大家有兴趣的话可以看看!!
下载资料整理——目录:http://blog.csdn.net/fanxiaobin577328725/article/details/51894331

  这篇博客里面是我关于我见到的感觉不错的好资源的整理,里面包含了书籍及源代码以及个人搜索的一些资源,如果有兴趣的可以看看,我会一直对其进行更新和添加。
优秀的文章&优秀的学习网站之收集手册:http://blog.csdn.net/fanxiaobin577328725/article/details/52753638

  这篇博客里面是我对于我读过的,并且感觉有意义的文章的收集整理,纯粹的个人爱好,大家感觉有兴趣的可以阅读一下,我也会时常的对其进行更新。

********************************************************************************感谢********************************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: