如何从 Xml 字符串创建文档
How to create a document from an Xml string
我想转换一个 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>
和对应的 xml 字符串符合 xsd :
<?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 生成的文档:
然后我有一个 Flow 服务,可以将 xml 字符串转换为文档
似乎有效,但实际上无效。
如果我添加一个简单的地图,它从未被处理过:
result 中的管道从不包含最后一张地图的值。使用调试模式后,我了解到 pub.xml:xmlStringToXMLNode
生成的文档与我的文档类型不同。
管道输出中的 Id
字符串丢失。
我的理解和我的例子有什么问题吗?
您的问题的答案在于您的第二张和第三张屏幕截图之间 mstns:EtdDaCisIUpdParty
变量的数据结构的细微差别:
你的第二张截图显示了你在声明变量时使用的文档引用的数据结构,这是结构的设计时视图(你期望数据结构看起来像什么):
- mstns:EtdDaCisIUpdParty
- mstns:wUpdatetsMax
- mstns:wTpsnEtendu
- ...
与你的第三张截图相比,它显示了 运行 时间的实际数据结构:
- mstns:EtdDaCisIUpdParty
- @version
- @encoding
- mstns:EtdDaCisIUpdParty
- mstns:wUpdatetsMax
- mstns:wTpsnEtendu
- ...
注意 运行-time 结构中的额外级别,其中包含 XML 序言属性 @version
和 @encoding
以及名为 [=12= 的子文档] 表示 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
--> mstns:EtdDaCisIUpdParty
,而不是 document
--> mstns:EtdDaCisIUpdParty
.
因为 document
是一个动态结构(它的结构只在 运行 时才知道,因为它取决于它解析的 XML),你需要手动创建一个IData 文档在调用 pub.xml:xmlNodeToDocument
的 Service Out 管道中将 mstns:EtdDaCisIUpdParty
作为 document
下的子项调用,然后从中映射:
- 右键单击 Service Out 管道中的
document
(不是右侧的 Pipeline Out),
- 插入一个新的文档变量
- 命名为
mstns:EtdDaCisIUpdParty
- 从服务输出管道中的
mstns:EtdDaCisIUpdParty
映射到管道输出中的变量mstns:EtdDaCisIUpdParty
。
此外,我建议您在调用 pub.xml:xmlNodeToDocument
时设置以下输入参数,以便一致地解析所有 XML 文档:
- 将
makeArrays
设置为 false
,因为如果您为 documentTypeName
指定一个值,则它是必需的
- 将
nsDecls/mstns
设置为 http://tempuri.org/XMLSchema.xsd
以便所有 XML 文档无论使用的名称空间前缀如何都被一致地解析(mstns
以外的前缀仍将表示为字段称为 mstns:fieldname
;除非您在 nsDecls
参数中声明名称空间,否则不会发生这种情况)
- 将
documentTypeName
设置为您用于声明变量 mstns:EtdDaCisIUpdParty
的文档引用,以便 XML 具有 maxOccurs > 1
的元素被一致地处理(始终被解析为数组即使有问题的元素只在 XML) 中出现过一次
并且为了防止您的服务被 unexpected/unsupported XML 文档调用,您可能应该调用 pub.schema:validate
以确保 XML 格式正确且有效您在上面提供的 XSD 或类似内容。
我想转换一个 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>
和对应的 xml 字符串符合 xsd :
<?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 生成的文档:
然后我有一个 Flow 服务,可以将 xml 字符串转换为文档
似乎有效,但实际上无效。 如果我添加一个简单的地图,它从未被处理过:
result 中的管道从不包含最后一张地图的值。使用调试模式后,我了解到 pub.xml:xmlStringToXMLNode
生成的文档与我的文档类型不同。
管道输出中的 Id
字符串丢失。
我的理解和我的例子有什么问题吗?
您的问题的答案在于您的第二张和第三张屏幕截图之间 mstns:EtdDaCisIUpdParty
变量的数据结构的细微差别:
你的第二张截图显示了你在声明变量时使用的文档引用的数据结构,这是结构的设计时视图(你期望数据结构看起来像什么):
- mstns:EtdDaCisIUpdParty
- mstns:wUpdatetsMax
- mstns:wTpsnEtendu
- ...
与你的第三张截图相比,它显示了 运行 时间的实际数据结构:
- mstns:EtdDaCisIUpdParty
- @version
- @encoding
- mstns:EtdDaCisIUpdParty
- mstns:wUpdatetsMax
- mstns:wTpsnEtendu
- ...
注意 运行-time 结构中的额外级别,其中包含 XML 序言属性 @version
和 @encoding
以及名为 [=12= 的子文档] 表示 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
--> mstns:EtdDaCisIUpdParty
,而不是 document
--> mstns:EtdDaCisIUpdParty
.
因为 document
是一个动态结构(它的结构只在 运行 时才知道,因为它取决于它解析的 XML),你需要手动创建一个IData 文档在调用 pub.xml:xmlNodeToDocument
的 Service Out 管道中将 mstns:EtdDaCisIUpdParty
作为 document
下的子项调用,然后从中映射:
- 右键单击 Service Out 管道中的
document
(不是右侧的 Pipeline Out), - 插入一个新的文档变量
- 命名为
mstns:EtdDaCisIUpdParty
- 从服务输出管道中的
mstns:EtdDaCisIUpdParty
映射到管道输出中的变量mstns:EtdDaCisIUpdParty
。
此外,我建议您在调用 pub.xml:xmlNodeToDocument
时设置以下输入参数,以便一致地解析所有 XML 文档:
- 将
makeArrays
设置为false
,因为如果您为documentTypeName
指定一个值,则它是必需的
- 将
nsDecls/mstns
设置为http://tempuri.org/XMLSchema.xsd
以便所有 XML 文档无论使用的名称空间前缀如何都被一致地解析(mstns
以外的前缀仍将表示为字段称为mstns:fieldname
;除非您在nsDecls
参数中声明名称空间,否则不会发生这种情况) - 将
documentTypeName
设置为您用于声明变量mstns:EtdDaCisIUpdParty
的文档引用,以便 XML 具有maxOccurs > 1
的元素被一致地处理(始终被解析为数组即使有问题的元素只在 XML) 中出现过一次
并且为了防止您的服务被 unexpected/unsupported XML 文档调用,您可能应该调用 pub.schema:validate
以确保 XML 格式正确且有效您在上面提供的 XSD 或类似内容。