我们有一个名为Camstar的托管应用程序。它提供了围绕WCF构建的SOAP Web服务。
我有一个有效载荷。我可以使用下面的有效负载从SoapUI调用Web服务。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soapenv:Header>
<WSShopFloorHeader xmlns="http://www.camstar.com/WebService/WSShopFloor">
<UserName>abc</UserName>
<Password>def</Password>
</WSShopFloorHeader>
</soapenv:Header>
<soapenv:Body>
<Submit xmlns="http://www.camstar.com/WebService/WSShopFloor">
<serviceData xmlns:ns0="http://www.camstar.com/WebService/DataTypes" ns0:type="LotStart">
<Factory>
<__CDOTypeName/>
<__name>X30</__name>
</Factory>
<Comments/>
<Workflow>
<__name>TESTSTOREWF</__name>
<__rev/>
<__useROR>true</__useROR>
</Workflow>
<WorkflowStep>
<__CDOTypeName/>
<__name>DBINTSINVSPEC</__name>
</WorkflowStep>
<Qty>1000</Qty>
<Qty2>10</Qty2>
<Product>
<__CDOTypeName/>
<__name>9672-02-9450-D00.BW</__name>
<__rev/>
<__useROR>true</__useROR>
</Product>
<StartReason>
<__CDOTypeName/>
<__name>NORMAL</__name>
</StartReason>
<Owner>
<__CDOTypeName/>
<__name>PROD</__name>
</Owner>
<Level>
<__CDOTypeName/>
<__name>LOT</__name>
</Level>
<ContainerName>TEST004</ContainerName>
</serviceData>
</Submit>
</soapenv:Body>
</soapenv:Envelope>
我无法弄清楚如何基于上述XML创建XSD。唯一的命名空间位于Submit和serviceData元素中,它们是内联的。
如果我需要从一个源到另一个源生成名称xml,如何创建XSLT?
答案 0 :(得分:1)
模式定义只能定义一个名称空间 - 因此您需要为所需的每个名称空间编写单独的模式定义。
由于您有两个名称空间(.../WSShopFloor
和.../DataTypes
- “...”只是我的缩写)。你需要两个模式定义。
让我们从简单的开始:.../DataTypes
命名空间的模式定义。我把它放在文件名“types.xsd”中 - 这对我们稍后import
时很重要。它只做 的事情是在目标命名空间中定义type
属性:
$ cat types.xsd
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.camstar.com/WebService/DataTypes"
>
<xsd:attribute name="type"/>
</xsd:schema>
现在为.../WSShopFloor
命名空间的模式定义。 (我不会做所有的内容,只是足以解决名称空间问题。我会假装<Factory>
只有字符串内容,并跳过其中的所有元素。)
<xsd:schema
elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://www.camstar.com/WebService/DataTypes"
xmlns:tns="http://www.camstar.com/WebService/WSShopFloor"
targetNamespace="http://www.camstar.com/WebService/WSShopFloor"
>
<xsd:import
namespace ="http://www.camstar.com/WebService/DataTypes"
schemaLocation = "types.xsd"/>
<xsd:import
namespace = "http://schemas.xmlsoap.org/soap/envelope/"
schemaLocation = "http://schemas.xmlsoap.org/soap/envelope/"/>
<xsd:element name="WSShopFloorHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="UserName" type="xsd:string"/>
<xsd:element name="Password" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Submit">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="serviceData">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Factory" type="xsd:string"/> <!-- skip -->
</xsd:sequence>
<xsd:attribute ref="ns0:type"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
首先,请参阅导入types.xsd
架构定义,并且(在顶部),ns0
引用相同的.../DataTypes
命名空间。进一步向下查看<serviceData>
元素定义,其中包含一个引用该命名空间中该定义的属性。
其次,我们还必须导入soap信封架构定义。 BTW:模式实际上位于命名空间URI,解析器下载它。你也可以下载它,并参考你给它的文件名(实际上,这就是我所做的 - 它运行得更快,而不是每次下载)。
为了您的兴趣,请查看.../soap/envelope
架构 - 它定义顶级元素<Envelope>
,因为我们导入它,我们的文档也可以将其作为顶级元素。 <Envelope>
定义了<Header>
和<Body>
个元素。 <Header>
可以包含任何内容,只要它位于不同的命名空间(##other
)中:
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
<Body>
可以包含任何内容(##any
- 也就是说,包括在此定义的内容,.../soap/envelope
,架构
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
processContents="lax"
表示只有在可以获取模式的情况下才会验证内容 - 如果它无法获取模式,则不会产生错误。因此,为了确保我的架构实际被使用,我故意引入了一个错误(例如在元素名称中插入一个字母),以查看是否报告了错误。
BTW:我想知道你的xml中是否有错误 - <serviceData>
元素来自ns0:type
命名空间的.../Datatypes
属性。但是这是从名称中使用的唯一东西......我希望如果元素被标记为“类型”,那么它的所有内容都来自该命名空间,这将使用xmlns
属性来完成。 ..也许这被省略了? [当然,我只是在这里猜测 - 也许这是正确的]
我也只是学习这个,所以上面可能有错误或误解 - 如果有人看到错误,请纠正我!
答案 1 :(得分:0)
我将分两部分回答这个问题:
1)SoSD XML的XSD: 好。分享我的个人经验..我们从第三方获得SOAP XML! SOAP XML实际上称为WSDL,具有一堆命名空间,在我们的实时业务中,这些命名空间发生了变化..
另一方面,如果您将其视为XML:
当您遇到具有不同节点的不同命名空间的XML文件时!我的意思是,为父节点提供的命名空间与子节点的命名空间不同。你需要创建多个与<import>
链接的XSD文件 13ren 已经发布了答案..但!!这种验证不适用于大多数XML解析器!我自己经历过!
我观察到它在MS-visual studio中工作,其中多个XSD分配工作!当你尝试在.Net中使用XmlValidatingReader
加载XML和XSD时,这就失败了!与任何其他在线验证工具相同的行为..
这个SOAP XML还有一个问题。它们带有一堆不同的Namespace,通过这种方法我们不能继续添加与Namespace数量一样多的XSD文件!!
我还尝试过尝试对Soap XML使用XSD的.net代码。 here is the link ..但我很害怕..我不能成功!
如果您手动验证XML,我会赞同13ren的方法!
2)XML的XSLT: XSLT是一种函数式编程语言(不是程序性的)。这就是你练习XSLT的方法:
首先,您尝试复制整个XML。了解其重要性
<copy> and <apply-templates select="@*|*|text()"/>
对..了解身份模板!! @和元素通过*和文本数据通知 必须理解text()..尝试添加和删除元素和属性..使用
<template match="element_or_Attribute_name"/>
删除元素/属性。 同样<value-of select=""/>
在这里进行了描述..尝试将属性转换为元素和反之亦然。
尝试在其他一些元素下移动一组元素或父标记.. 使用并理解
<for-each select=""/>
的重要性(它会 这里有必要..)..也写代码重命名标签.. 和属性..使用不同的子标记名称和孙标记构建一个巨大的XML 构建一个可以添加和删除大量标签的XSL。使用所有这些可能性 您在此之前尝试过(一次一个)