我们有一个名为Camstar的托管应用程序。它提供了基于WCF构建的SOAP webservices。
我有一个可以工作的有效载荷。我可以使用下面的有效负载从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?
发布于 2012-11-29 20:45:38
我将分两部分回答这个问题:
1) XSD for Soap XML: Well。分享我的个人经历..我们从第三方得到SOAP XML!SOAP实际上称为WSDL,它有很多命名空间,在我们实时业务中,这些命名空间会发生变化。
另一方面,如果您将其视为XML:
当您遇到针对不同节点具有不同名称空间的XML文件时!我的意思是,父节点的命名空间与子节点的命名空间不同。您需要找到多个链接到<import> 13ren的XSD文件已经发布了答案。但是!!这种验证不适用于大多数XML解析器!我自己也经历过!
我观察到它在MS-visual studio中工作,其中XSD的多重赋值工作!当您尝试在.Net中使用XmlValidatingReader加载XML和XSD时,这将失败!!与任何其他在线验证工具的行为相同。
这个SOAP XML还有一个问题。它们承载了一堆不同的命名空间,通过这种方法,我们不能一直添加与命名空间数量一样多的XSD文件!!
我还尝试过对Soap XML使用XSD的.net代码。here is the link ..但我恐怕..。我不能很好地成功!
如果你要手动验证XML,我推荐13ren的方法!
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。使用你之前尝试过的所有这些可能性(一次一个)
发布于 2012-11-29 19:11:07
模式定义只能定义一个名称空间,因此您需要为所需的每个名称空间编写单独的模式定义。
由于您有两个名称空间(.../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信封模式定义。顺便说一下:模式实际上位于名称空间URI,解析器下载它。你也可以下载它,并引用你给它的文件名(实际上,这就是我所做的-它运行得更快,而不需要每次都下载)。
为了引起您的兴趣,请看一下.../soap/envelope模式-它定义了顶级元素<Envelope>,因为我们导入了它,所以我们的文档也可以将其作为顶级元素。<Envelope>定义了<Header>和<Body>元素。只要内容位于不同的命名空间(##other)中,<Header>可以包含任何内容:
<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"意味着它只在能够获得模式的情况下才验证内容-如果不能获得模式,则不会给出错误。因此,为了确保我的模式确实被使用,我故意引入了一个错误(例如,在元素名称中插入一个字母),以查看是否报告了错误。
顺便说一下:我想知道您的xml中是否有错误-- <serviceData>元素有一个来自.../Datatypes名称空间的ns0:type属性。但这是该命名空间中唯一使用的东西...我期望如果元素被标记为“类型”,那么它的所有内容都来自该名称空间,这将通过一个xmlns属性来完成……所以这可能被省略了?当然,我只是在猜测--也许它是正确的
我也正在学习这一点,所以上面可能有错误或误解-如果有人看到错误,请纠正我!
https://stackoverflow.com/questions/13609898
复制相似问题