如何从Xml字符串

时间:2015-07-24 12:49:52

标签: xml webmethods

我想转换一个xml字符串(她自己用外部工具从字节数组构建。

我的文档和我的输入字符串都是使用相同的xsd创建的 我用pub.string:stringToBytes读取了字符串,然后从pub.xml:xmlStringToXMLNode

获取了一个XmlNode

这部分效果很好。

我会在之后创建一个文档,称之为Doc。 我打电话给pub.xml:xmlNodeToDocument。但是返回的文档的类型不正确。 我的意思是所有数据都是正确的,但是当我试图将一些数据映射到另一个文档时,它永远不会有效。

我知道不清楚,对不起。 所以,详细说来,我有一个简单的xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:complexType name="EtdDaCisIUpdParty">
    <xs:sequence>
      <xs:element name="wUpdatetsMax">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:maxLength value="15"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="wTpsnEtendu" type="WTpsnEtendu"/>
      <xs:element name="wTpsnExt" type="WTpsnExt" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="WTpsnEtendu">
    <xs:sequence>
      <xs:element name="Id" type="xs:string"></xs:element>
      <xs:element name="Name" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="WTpsnExt">
    <xs:sequence>
      <xs:element name="key" type="xs:string"></xs:element>
      <xs:element name="value" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="EtdDaCisIUpdParty" type="EtdDaCisIUpdParty" />

</xs:schema>

符合此xsd的对应xml字符串:

<?xml version="1.0" encoding="utf-8"?>
<mstns:EtdDaCisIUpdParty  xmlns:mstns="http://tempuri.org/XMLSchema.xsd" >
    <mstns:wUpdatetsMax>40</mstns:wUpdatetsMax> 
    <mstns:wTpsnEtendu>
        <mstns:Id>13</mstns:Id>
        <mstns:Name>Test</mstns:Name>
    </mstns:wTpsnEtendu>
    <mstns:wTpsnExt>
        <mstns:key>1</mstns:key>
        <mstns:value>one</mstns:value>
    </mstns:wTpsnExt>
    <mstns:wTpsnExt>
        <mstns:key>2</mstns:key>
        <mstns:value>something</mstns:value>
    </mstns:wTpsnExt>
    <mstns:wTpsnExt>
        <mstns:key>3</mstns:key>
        <mstns:value>nothing</mstns:value>
    </mstns:wTpsnExt>
</mstns:EtdDaCisIUpdParty>

使用相同的xsd生成的文档: enter image description here

然后我有一个Flow服务将xml字符串转换为文档

enter image description here

它似乎有效,但事实并非如此。 如果我添加一个简单的地图,它从未被处理过:

enter image description here

结果中的管道永远不会包含最后一个映射的值。使用调试模式后,我理解pub.xml:xmlStringToXMLNode生成的文档与我的文档类型不同。

enter image description here

管道输出中的Id字符串丢失。

我的理解和我的榜样出了什么问题?

1 个答案:

答案 0 :(得分:3)

您的问题的答案在于mstns:EtdDaCisIUpdParty变量的第二个和第三个屏幕截图之间的数据结构的细微差别:

您的第二个屏幕截图显示了您在声明变量时使用的文档引用的数据结构,这是结构的设计时视图(您期望数据结构看起来像):

- mstns:EtdDaCisIUpdParty
  - mstns:wUpdatetsMax
  - mstns:wTpsnEtendu
  - ...

与您的第3个屏幕截图相对应,它显示了运行时的实际数据结构:

- mstns:EtdDaCisIUpdParty
  - @version
  - @encoding
  - mstns:EtdDaCisIUpdParty
     - mstns:wUpdatetsMax
     - mstns:wTpsnEtendu
     - ...

请注意运行时结构中的额外级别,其中包含XML prolog属性@version@encoding以及一个名为mstns:EtdDaCisIUpdParty的子文档,表示XML文档的根节点。

虽然您已将管道变量mstns:EtdDaCisUpdParty声明为文档引用,但在运行时无关紧要且无效。文档引用让webMethods Designer在GUI中向您展示您期望的数据结构,这使您可以更轻松地在设计时使用它。但是,文档引用不会在运行时强制执行。

在运行时,因为您已从document的顶级映射到mstns:EtdDaCisUpdParty,所以它与document具有相同的结构,这与文档引用不同在设计时使用。这就是为什么你的地图步骤不起作用的原因。 mstns:EtdDaCisIUpdParty/mstns:wTpsnEtendu/mstns:Id变量在运行时实际上并不存在于管道中,而是在结构中更深一层:mstns:EtdDaCisIUpdParty/mstns:EtdDaCisIUpdParty/mstns:wTpsnEtendu/mstns:Id

您可以通过从结构中的下一级向下映射来修复您的Flow服务:document/mstns:EtdDaCisIUpdParty - &gt; mstns:EtdDaCisIUpdParty,而不是document - &gt; mstns:EtdDaCisIUpdParty

因为document是一个动态结构(它的结构只在运行时才知道,因为它依赖于它解析的XML),所以你需要手动创建一个名为mstns:EtdDaCisIUpdParty的IData文档作为调用document服务输出管道中的pub.xml:xmlNodeToDocument下面的子项,然后从中映射:

  1. 右键点击服务输出管道中的document(而不是右侧的管道输出),
  2. 插入新的文档变量
  3. 将其命名为mstns:EtdDaCisIUpdParty
  4. 服务输出管道中的mstns:EtdDaCisIUpdParty映射到管道输出中的变量mstns:EtdDaCisIUpdParty
  5. 另外,我建议您在调用pub.xml:xmlNodeToDocument时设置以下输入参数,以便始终解析所有XML文档:

    • makeArrays设置为false,因为如果您为documentTypeName
    • 指定值,则需要nsDecls/mstns
    • http://tempuri.org/XMLSchema.xsd设置为mstns,以便无论所使用的命名空间前缀如何都会一致地解析所有XML文档(mstns:fieldname以外的前缀仍将表示为名为nsDecls的字段;除非您在documentTypeName参数)
    • 中声明名称空间,否则不会发生这种情况
    • mstns:EtdDaCisIUpdParty设置为您用于声明变量maxOccurs > 1的文档引用,以便一致地处理具有pub.schema:validate的XML元素(即使有问题的元素,也始终将其解析为数组只在XML中出现过一次)

    为防止使用意外/不支持的XML文档调用您的服务,您应该调用 //create a delegate for event of documeent completed to combat multiple firings of the event this.webBrowser1.DocumentCompleted += delegate { if (complete) return; complete = true; // DocumentCompleted is fired before window.onload and body.onload this.webBrowser1.Document.Window.AttachEventHandler("onload", delegate { //if all awaiting threads have been fired the DOM is accessible System.Threading.SynchronizationContext.Current.Post(delegate { //navigate navigate("https://website.com"); }, null); }); }; //registering new evenhandler on document complete webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); 以确保XML格式正确且对您上面提供的XSD或类似内容有效。