我想转换一个xml字符串(她自己用外部工具从字节数组构建。
我的文档和我的输入字符串都是使用相同的xsd创建的
我用pub.string:stringToBytes
读取了字符串,然后从pub.xml:xmlStringToXMLNode
这部分效果很好。
我会在之后创建一个文档,称之为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>
然后我有一个Flow服务将xml字符串转换为文档
它似乎有效,但事实并非如此。 如果我添加一个简单的地图,它从未被处理过:
结果中的管道永远不会包含最后一个映射的值。使用调试模式后,我理解pub.xml:xmlStringToXMLNode
生成的文档与我的文档类型不同。
管道输出中的Id
字符串丢失。
我的理解和我的榜样出了什么问题?
答案 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
下面的子项,然后从中映射:
document
(而不是右侧的管道输出),mstns:EtdDaCisIUpdParty
mstns:EtdDaCisIUpdParty
映射到管道输出中的变量mstns:EtdDaCisIUpdParty
。另外,我建议您在调用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或类似内容有效。