我正在研究一个大的模式映射。映射的任务之一是规范化特殊数据类型值。对于具有此数据值的每个元素,需要将 Src 值发送到外部程序集以进行"规范化"。
在 src 和 dst 架构中都有数百个这样的元素。它使映射文件非常大且难以维护。
我想知道我是否可以使用某种 xslt 功能甚至自定义的 xslt 来简单地将所有元素与此数据类型匹配并进行映射。
对于所有其他元素映射,只需值复制就足够了,但 src 和 dst 具有不同的目标模式。
有什么建议吗?
更新:我创建了一个简单的架构来解释我的情况:下面的架构。可以假设存在另一个具有相同结构但目标命名空间不同的架构。映射需要找到数据类型为"NM"的所有元素,并将其值提供给外部程序集。(假设它是一个简单的 C# 字符串。反向())然后将值输出到 dst 架构元素中的同一节点。
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://BizTalk_Server_Project1.Schema1" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://BizTalk_Server_Project1.Schema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Record1">
<xs:complexType>
<xs:sequence>
<xs:element name="R2">
<xs:complexType>
<xs:sequence>
<xs:element name="R3">
<xs:complexType>
<xs:sequence>
<xs:element name="UsedName">
<xs:simpleType>
<xs:restriction base="NM" />
</xs:simpleType>
</xs:element>
<xs:element name="Age">
<xs:simpleType>
<xs:restriction base="xs:int" />
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="AnotherName">
<xs:simpleType>
<xs:restriction base="NM">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="Gender">
<xs:simpleType>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="NM">
<xs:maxLength value="10" />
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="NM">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
不能用 XSLT 1.0 完成(但显然 2.0 可以做到? 我不太确定,但这并不重要,因为 BizTalk 和 .NET 不支持 2.0)。
一种方法是从架构(指定数据类型)生成节点列表(可能带有它们的 XPath)。 您可以通过编程方式执行此操作(也许在 XSD 文件上使用 XSLT? 使用 .NET 类解析它?或硬编码。 一旦您生成列表,我可能会选择硬编码它。 理想情况下,该列表将包含一组唯一的节点名称或 XPath(可能带有命名空间的占位符)。 在这一点上,我会选择某种.NET实现(使用XDocument或XPathNavigator),做这样的事情。
XDocument xdoc = XDocument.Parse(xmlInput);
foreach (string xPath in ListOfXPaths)
{
NormalizeData(xdoc.XPathSelectElement(string.Format(xPath, "proper namespace for trading partner here")));
}
...
NormalizeData(XElement el)
{
el.Value = something else;
}
您可以在映射之前或之后执行此操作 - 如果消息来自贸易合作伙伴,则在之后执行此操作,否则在之前执行此操作(这样您可以更好地控制命名空间)。
如果这是真的EDI X12,那么传入的文件应该给出ST01中的文件类型。如果可以将进程配置为检查该字段,则可以区分文件类型。