XQuery/XQuery 和 XML Schema
外观
< XQuery
在学习任何建模语言时,查看任何形式模型的示例实例都很有帮助。在开发 XML Schema 时,这一点同样适用。像 Oxygen 和 XML-Spy 这样的 XML 开发工具具有生成提供的 XML Schema 的随机实例的工具,但拥有一个 Web 服务来执行此操作也很有用。该服务也可用于测试数据生成。
以下是一个测试 XML Schema 文件
<xs:group name="TechnicalOrderVersionChoiceGroup">
<xs:choice>
<xs:element name="ettcsMigrationTov" type="ord:ETTCSMigrationTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsNewSiteBuildTov" type="ord:ETTCSNewSiteBuildTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsNewCabinetTov" type="ord:ETTCSNewCabinetTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsSimpleTov" type="ord:ETTCSSimpleTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="lteNewCabinetTov" type="ord:LTENewCabinetTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="gsmoeTov" type="ord:GSMoETechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsUpspeedTov" type="ord:ETTCSUpspeedTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsRehomeTov" type="ord:ETTCSRehomeTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsRebalanceTov" type="ord:ETTCSRebalanceTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="retTechnicalOrderVersion" type="ord:RETTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsNSBNGUNIEVCUplinkTechnicalOrderVersion" type="ord:ETTCSNSBNGUNIEVCUplinkTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsNSBNGUNIEVCAdditionalNode" type="ord:ETTCSNSBNGUNIEVCAdditionalNodeTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="eireTov" type="ord:EIRETechnicalOrderVersionType" minOccurs="0" />
<!-- Granite Initiated Order Types -->
<xs:element name="addEttcsMtsoCollectorCircuitTechnicalOrderVersion" type="ord:AddEttcsMtsoCollectorCircuitTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="r2BToR4BConversionTechnicalOrderVersion" type="ord:R2BToR4BConversionTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="eoSONETMtsoCollectorCircuitTechnicalOrderVersion" type="ord:EoSONETMtsoCollectorCircuitTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="disconnectEthernetEvcSegmentTechnicalOrderVersion" type="ord:DisconnectEthernetEvcSegmentTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcOc3MtsoR4DTechnicalOrderVersion" type="ord:EttcOc3MtsoR4DTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="gSMoEMtsoTechnicalOrderVersion" type="ord:GSMoEMtsoTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="disconnectLnsOewBaseSegmentTechnicalOrderVersionType" type="ord:DisconnectLnsOewBaseSegmentTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="disconnectLnsOewBaselinePathTechnicalOrderVersionType" type="ord:DisconnectLnsOewBaselinePathTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="discoEthernetSonetRehomeTov" type="ord:DiscoEthernetOverSonetForRehomeTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ethernetSonetRehomeMtsoTov" type="ord:EthernetOverSonetRehomeMtsoTechnicalOrderVersionType" minOccurs="0" />
<!-- Iteration 17 - Two new Granite Initiated Order Types - for Aug2013 -->
<xs:element name="gEttcsNSBNextGenUniEvcDualUplinkTov" type="ord:EttcsNSBNextGenUNIEVCDualUplinkTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="gEttcsNSBNextGenUniEvcMultiCabTov" type="ord:EttcsNSBNextGenUNIEVCMultiCabTechnicalOrderVersionType" minOccurs="0" />
<!-- R12.1 INDOOR SMALL CELL EAMIS -->
<xs:element name="smallCellEamis" type="ord:IndoorSmallCellEamisTechnicalOrderVersionType" minOccurs="0" />
<!-- R13.1 Rapid Deployment-->
<xs:element name="eoSonetOc12MtsoCollectorCircuitTov" type="ord:EoSonetOc12MtsoCollectorCircuitTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="indoorSmallCellBdslTov" type="ord:IndoorSmallCellBdslTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="indoorSmallCell3RdPartyTov" type="ord:IndoorSmallCell3RdPartyTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="indoorSmallCellSharedTransportTov" type="ord:IndoorSmallCellSharedTransportTechnicalOrderVersionType" minOccurs="0" />
<!-- MLPPP WO Types -->
<xs:element name="mlpppMigrationUMTS" type="ord:MLPPPMigrationUMTSTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppMigrationDS1UMTS" type="ord:MLPPPMigrationDS1UMTSTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppNewCabinetAddLTE" type="ord:MLPPPNewCabinetAddLTETechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppNewCabinetAddDS1LTE" type="ord:MLPPPNewCabinetAddDS1LTETechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppNewCabinetAddUMTS" type="ord:MLPPPNewCabinetAddUMTSTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppNewCabinetAddDS1UMTS" type="ord:MLPPPNewCabinetAddDS1UMTSTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppUpspeed" type="ord:MLPPPUpspeedTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppUpspeedDS1" type="ord:MLPPPUpspeedDS1TechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppRehome" type="ord:MLPPPRehomeTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppRehomeDS1" type="ord:MLPPPRehomeDS1TechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppRebalance" type="ord:MLPPPRebalanceTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="mlpppRebalanceDS1" type="ord:MLPPPRebalanceDS1TechnicalOrderVersionType" minOccurs="0" />
<!-- ESCORE Initiated SmallCell WO Type - since R14.0 -->
<xs:element name="smallcellTransport" type="ord:SmallCellTransportTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="smallcellSCR" type="ord:SmallCellSCRTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="smallcellSCS" type="ord:SmallCellSCSTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="smallcellAP" type="ord:SmallCellAPTechnicalOrderVersionType" minOccurs="0" /> <!-- Self install and Disconnect will use this same AP payload -->
<!-- Since R1406 - Two new ETTCS automation IPv6 Types -->
<xs:element name="ettcsIPv6Siad" type="ord:ETTCSIPv6MigrationSIADTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsIPv6ENodeB" type="ord:ETTCSIPv6MigrationENodeBTechnicalOrderVersionType" minOccurs="0" />
<!-- Since R1404 - RD Types -->
<xs:element name="ettcsUniversalEvcDownspeed" type="ord:EttcsUniversalEvcDownspeedTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="outdoorSmallCell3rdPartytTov" type="ord:OutdoorSmallCell3rdPartyTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="outdoorSmallCellBdslTov" type="ord:OutdoorSmallCellBdslTechnicalOrderVersionType" minOccurs="0" />
<!-- Since R1406 - ETTCS Site Migration -->
<xs:element name="ettcsSiteMigrBackhaul" type="ord:ETTCSSiteMigrationBackhaulTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="ettcsSiteMigrShorthaul" type="ord:ETTCSSiteMigrationShorthaulTechnicalOrderVersionType" minOccurs="0" />
<!-- Since R1410 - IUB Trunking Support -->
<xs:element name="iubTrunkingTov" type="ord:IUBTrunkingTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="infrastructureTov" type="ord:InfrastructureTechnicalOrderVersionType" minOccurs="0" />
<xs:element name="EOMWTargetTov" type="ord:ETTCSNSBNGUplinkEoMWTargetTechnicalOrderVersionType" minOccurs="0" />
</xs:choice>
</xs:group>
我们可以使用递归函数将此 XML Schema 转换为实例文档。这是一个此函数的实现,它涵盖了一些关键的 XML Schema 结构
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare function local:process-element($element as node()) {
typeswitch ($element)
case element(xs:complexType) return
for $sub-element in $element/*
return local:process-element($sub-element)
case element(xs:annotation) return
()
case element(xs:element) return
let $min := ($element/@minOccurs,1)[1]
let $max :=
if ($element/@maxOccurs = "unbounded")
then 10
else ($element/@maxOccurs,1)[1]
let $count := $min + round(math:random() * ($max - $min))
return
if ($count >0 )
then
for $i in 1 to $count
return
if ($element/@ref)
then
local:process-element(root($element)/xs:schema/xs:element[@name=$element/@ref])
else
if (root($element)/xs:schema/xs:complexType[@name=$element/@type])
then
element {$element/@name} {
local:process-element(root($element)/xs:schema/xs:complexType[@name=$element/@type])
}
else
element {$element/@name} {
if ($element/*)
then for $sub-element in $element/*
return local:process-element($sub-element)
else local:process-type(($element/@type,"xs:string")[1])
}
else ()
case element(xs:attribute) return
if ($element/@use="required" or math:random() > 0.5)
then
attribute {$element/@name} {
local:process-type($element/@type)
}
else ()
case element(xs:sequence) return
for $sub-element in $element/*
return local:process-element($sub-element)
case element(xs:all) return
for $sub-element in $element/*
order by math:random()
return local:process-element($sub-element)
case element(xs:choice) return
let $count := count($element/*)
let $i := ceiling(math:random()*$count)
let $sub-element := $element/*[ $i]
return local:process-element($sub-element)
default return
()
};
此函数使用element结构基于 XML Schema 文件中的信息创建一个新的 XML 实例树,并使用typeswitch结构选择给定元素类型的适当处理。
需要一些辅助函数来生成(某些)标准类型的随机实例。
declare function local:pad($string as xs:string, $char as xs:string, $max as xs:integer) as xs:string {
concat(string-pad($char,$max - string-length($string)), $string)
};
declare function local:pad2($string) {
local:pad($string,"0",2)
};
declare function local:process-type($name ) {
(: just simple types - xs namespace :)
if ($name = ("xs:string","xs:NMTOKEN","xs:NCName"))
then string-join(
for $c in 1 to math:random() * 12
return ("A","B","C","D")[ceiling(math:random() * 4)]
, "")
else if ($name="xs:integer")
then round(math:random()*100)
else if ($name="xs:decimal")
then math:random() * 100 - 50
else if ($name="xs:boolean")
then ("true","false")[ ceiling( math:random() *2)]
else if ($name="xs:date")
then string-join((1990 + round(math:random() * 20),
local:pad2(ceiling(math:random()*12)) ,
local:pad2(ceiling(math:random()*30))),"-")
else if ($name="xs:time")
then string-join((local:pad2(floor(math:random() * 24)),
local:pad2(floor(math:random()*60)) ,
local:pad2(floor(math:random()*60))),":")
else if ($name="xs:dateTime")
then concat (
string-join((1990 + round(math:random() * 20),
local:pad2(ceiling(math:random()*12)) ,
local:pad2(ceiling(math:random()*30))),"-"),
"T",
string-join((local:pad2(floor(math:random() * 24)),
local:pad2(floor(math:random()*60)) ,
local:pad2(floor(math:random()*60))),":")
)
else ()
};
这是一个基本脚本,它将此函数应用于示例模式。默认情况下,生成的实例的根是模式中的第一个元素,或者如果提供了根参数,则为命名元素。
let $file := request:get-parameter("file",())
let $root := request:get-parameter("root",())
let $schema := doc($file)
return
if ($root)
then local:process-element($schema/xs:schema/xs:element[@name=$root])
else local:process-element($schema/xs:schema/xs:element[1])
<Root>
<Start>C</Start>
<Any>
<AnyA>BADADAD</AnyA>
<AnyC>BA</AnyC>
<AnyB>D</AnyB>
</Any>
<Multiple>
<Choice>
<Third AttributeDecimal="8.937041402178778" AttributeTime="20:38:04" AttributeDateTime="1995-08-06T21:08:43"/>
</Choice>
<Unbounded>BDAACAAAA</Unbounded>
<Ref>
<Ref1>52</Ref1>
<Ref2>1992-09-02</Ref2>
</Ref>
<WithRefType>
<RefTypeA>BBBDD</RefTypeA>
<RefTypeB>DAADCABDC</RefTypeB>
</WithRefType>
</Multiple>
<Multiple>
<Choice>
<Second AttributeString="ADAB" AttributeDate="2005-12-16"/>
</Choice>
<Unbounded/>
<Unbounded>CABBB</Unbounded>
<Unbounded/>
<Unbounded>B</Unbounded>
<Unbounded>AACBABAABCB</Unbounded>
<Ref>
<Ref1>56</Ref1>
<Ref2>1992-05-22</Ref2>
</Ref>
<WithRefType>
<RefTypeA>CDAA</RefTypeA>
<RefTypeB>CBDBDBDB</RefTypeB>
</WithRefType>
<Optional>CC</Optional>
</Multiple>
<Multiple>
<Choice>
<First AttributeInt="21" AttributeString="AABC" AttributeBoolean="true"/>
</Choice>
<Unbounded>ADADDDDDB</Unbounded>
<Unbounded>DCDCBDDD</Unbounded>
<Unbounded>CBAD</Unbounded>
<Unbounded>DAAAD</Unbounded>
<Ref>
<Ref1>13</Ref1>
<Ref2>1997-04-30</Ref2>
</Ref>
<WithRefType>
<RefTypeA>CB</RefTypeA>
<RefTypeB/>
</WithRefType>
</Multiple>
<Multiple>
<Choice>
<Second AttributeString="DBDA" AttributeDate="1999-05-16"/>
</Choice>
<Unbounded>CCDDDDCD</Unbounded>
<Unbounded>DDABACC</Unbounded>
<Ref>
<Ref1>44</Ref1>
<Ref1>30</Ref1>
<Ref1>57</Ref1>
<Ref2>1997-01-26</Ref2>
</Ref>
<WithRefType>
<RefTypeA>CBC</RefTypeA>
<RefTypeB>CA</RefTypeB>
</WithRefType>
</Multiple>
<End>95</End>
</Root>
- 完整的一套 xml 类型
- 混合
- 限制(目前仅限枚举)
- 组
- 属性组
- complexType 中缺少属性的问题
- 分发的提示
- 命名空间
- 随机化配置