2012-11-28 82 views
3

我们有一个名为Camstar的托管应用程序。它提供围绕WCF构建的SOAP webservices。带内联命名空间的XSD

我有一个工作负载。我可以使用下面的负载从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元素中,并且它们是内联的。

另外如何创建XSLT,如果我需要从一个源生成名称xml到另一个?

+1

你有两个问题!这两个问题的答案是完全不同的,彼此无关! –

+1

@ InfantProgrammer'Aravind'请问你是否对第一个问题有点友好?只关注这个问题 - 不需要夸大和感叹。我发现(主要)是一个友善和乐于助人的社区,我想保留并鼓励这一点。如果您知道XSD问题的答案,我很有兴趣了解。 – 13ren

+0

@ user1860519请为您的XSLT问题创建一个新问题,并澄清您询问的内容(例如,我认为“姓名”可能是错字)。 SO(以及许多其他的东西)通过一次完成一件事情来发挥最佳效果。 – 13ren

回答

0

我将分两部分回答这个问题:对于SOAP XML

1)XSD: 嘛。分享我的个人经验..我们从第三方获取SOAP XML!实际上称为WSDL SOAP个XML,在我们的实时业务,这些命名空间变化的命名空间和一堆..

在另一方面,如果你把它当作一个XML:
当你遇到XML文件对于不同的节点有不同的命名空间!我的意思是,父目录的名称空间与子节点不一样..你需要与多个XSD文件连接<import>13ren已经发布了一个答案..但是!!这种验证不适用于大多数XML解析器!我自己经历过!

我已经观察到它在MS-visual studio中工作,其中XSD的多个赋值工作!当您尝试在.Net中使用XmlValidatingReader加载XML和XSD时,此失败!与任何其他在线验证工具相同的行为..

而且这个SOAP XML还有一个问题。他们携带一堆不同的命名空间,通过这种方法,我们无法继续添加尽可能多的XSD文件作为命名空间的数量!

我也尝试过使用XSD对付Soap XML的.NET代码。 here is the link ..但我担心..我不能成功!

我赞成13ren的方法,如果您手动验证XML!

2)XML的XSLT: XSLT是一种功能性编程语言(不是程序性的)。这是你如何去练XSLT:

首先,你尝试复制整个XML,因为它是..学习双..了解身份模板的意义!由属性 通知@和由*和文本数据元素作为 文本()已经被理解..

尝试添加和删除,元素和属性..使用<template match="element_or_Attribute_name"/>以除去元素/属性.. 也<value-of select=""/>在这里进入图片..

尝试将属性转换为elments和副诗..

尝试下其他一些.. 使用移动一组元素,或父标签..和理解<for-each select=""/>意义(这将 有必要在这里..)..还编写代码来重命名标签.. 和属性..

建立一个庞大的XML具有不同的子标签名称和孙子标签 建立一个XSL可以添加和删除大量的标签..使用所有那些你试图可能性 (一次一个)在此之前

供您参考的教程: https://stackoverflow.com/questions/1858345/xsltwhich-is-the-best-tutorial-you-would-like-to-recommend

+0

是的,我还发现在线验证工具只能接受一个模式......我想也许,如果您在其他地方托管了其他模式,并且在“import/@ schemaLocation”中使用了该URL,它可能会工作 - 但这就是真的很尴尬。 :) ** Re .Net:**我不使用.Net,但我认为有*必须*是一种指定多个模式的方式......啊!对于一组模式,XmlValidatingReader有一个[Schemas属性](http://msdn.microsoft.com/en-us/library/system.xml.xmlvalidatingreader.schemas.aspx)。 (注意:它也表示它已经“过时”了......) – 13ren

+0

@ 13ren,我记得正确指定了'import/@ schemaLocation'!好。我还尝试使用XSD生成器在线为Soap XML生成Schema文件。当然,他们产生,但他们不工作! –

+0

@ 13ren,是的.Net不支持太多.. :( –

0

模式定义只能定义一个名称空间 - 因此您需要为每个需要的名称空间编写单独的模式定义。

由于您有两个命名空间(.../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属性来完成......所以也许那被省略了? [当然,我只是在这里猜测 - 也许这是正确的]

我也只是在学习,所以上面可能会有错误或误解 - 如果有人看到错误,请更正我!

+0

这真的很有帮助。非常感谢。 – RKS