缺少命名空间前缀时 BizTalk 映射不工作
BizTalk map not working when namespace prefix is missing
我无法让我的 BizTalk 映射在信封去批处理后处理消息。该地图似乎需要命名空间前缀,但分批处理的消息没有前缀。如果我向根添加前缀,例如 <ns0:Encounter xmlns:ns0="http://hl7.org/fhir/Encounters">
,那么当我在 visual studio 中使用测试地图时,地图会正常工作。没有前缀,我仍然可以从映射中获得输出,但只有常量被映射到目标模式,没有任何内容从源模式映射。
我收到每个映射元素的以下错误消息
"error btm1044: Input validation error: The 'value' attribute is not declared."
我已经尝试按照单独 post 上的建议将 elementFormDefault 的值从不合格更改为合格,但仍然没有成功。
信封拆包后,我得到以下 XML。请注意,没有名称空间前缀。
如果我停止发送端口并查看分批处理的消息,则 MessageType 为 http://hl7.org/fhir/Encounters#Encounter .
<?xml version="1.0" encoding="utf-8"?>
<Encounter xmlns="http://hl7.org/fhir/Encounters">
<id value="ac34e2c2-6080-4c46-9ec5-d7340a7c4177" />
<extension url="https://api-foo.org/documents/fhir/extensions/encounter-facility">
<valueString value="foo" />
</extension>
<extension url="https://api-foo.org/documents/fhir/extensions/encounter-service">
<valueString value="fooo" />.......
我的架构如下所示
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://hl7.org/fhir/Encounters" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://hl7.org/fhir/Encounters" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Encounter">
<xs:complexType>
<xs:sequence>
<xs:element name="id">
<xs:complexType>
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="extension">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="valueInteger">
<xs:complexType>
<xs:attribute name="value" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="valueString">
<xs:complexType>
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="url" type="xs:string" use="required" />
</xs:complexType>
</xs:element> ............
有没有办法让 map/schema 按原样处理消息,或者有办法让分批处理的消息具有前缀。
我还有一个自定义管道组件,用于在分批处理之前更改传入消息的命名空间。我不确定这是否会导致下面的代码出现问题。
public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
{
if (Enabled)
{
try
{
IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart != null)
{
string json;
using (Stream originalDataStream = bodyPart.GetOriginalDataStream())
{
if (originalDataStream != null)
{
//Read the json message
using (TextReader tr = new StreamReader(originalDataStream))
{
json = tr.ReadToEnd();
}
//Use FHIR-NET-API to create a FHIR resource from the json
Hl7.Fhir.Serialization.ResourceReader resourceReader = new Hl7.Fhir.Serialization.ResourceReader(FhirJsonParser.CreateFhirReader(json), ParserSettings.Default);
//switch the namespace
var doc = XElement.Parse(Hl7.Fhir.Serialization.FhirSerializer.SerializeToXml(resourceReader.Deserialize()));
XNamespace toNs = Namespace;
doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
var ele = doc.DescendantsAndSelf();
foreach (var el in ele)
el.Name = toNs + el.Name.LocalName;
//Create the new BizTalk message
var memoryStream = new MemoryStream();
doc.Save(memoryStream);
// memoryStream.Write(resourceXmlBytes, 0, resourceXmlBytes.Length);
memoryStream.Position = 0;
inmsg.BodyPart.Data = memoryStream;
}
}
}
return inmsg;
}
catch (Exception e)
{
GenericEventLogger.LogEvent(
ExceptionSource,
String.Format("An exception [{0}] occured in [{1}( )]. \n\nMessage: \n{2} \n\nStack Trace: \n{3}",
e.GetType().Name,
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName,
e.Message,
e.StackTrace),
EventLogEntryType.Error,
999);
throw;
}
}
return inmsg;
}
这是信封架构
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://hl7.org/fhir/Encounters" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://hl7.org/fhir/Encounters" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo is_envelope="yes" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Bundle">
<xs:annotation>
<xs:appinfo>
<b:recordInfo body_xpath="/*[local-name()='Bundle' and namespace-uri()='http://hl7.org/fhir/Encounters']/*[local-name()='entry' and namespace-uri()='http://hl7.org/fhir/Encounters']/*[local-name()='resource' and namespace-uri()='http://hl7.org/fhir/Encounters']" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="total">
<xs:complexType>
<xs:attribute name="value" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="entry">
<xs:complexType>
<xs:sequence>
<xs:element name="resource">
<xs:complexType>
<xs:sequence>
<xs:element name="Encounter">
<xs:complexType>
<xs:sequence>
<xs:any />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
由于您使用的是 FHIR 的 JSON 表示,第一个问题应该是您是否需要使用 Xml 命名空间。
在 BizTalk 中处理本机 JSON 内容时,我的建议是在所有 Xml 处理中使用空命名空间。
您可以参考这篇维基文章了解更多详情:BizTalk: Simplify BizTalk Dev by Using the Empty Namespace
我无法让我的 BizTalk 映射在信封去批处理后处理消息。该地图似乎需要命名空间前缀,但分批处理的消息没有前缀。如果我向根添加前缀,例如 <ns0:Encounter xmlns:ns0="http://hl7.org/fhir/Encounters">
,那么当我在 visual studio 中使用测试地图时,地图会正常工作。没有前缀,我仍然可以从映射中获得输出,但只有常量被映射到目标模式,没有任何内容从源模式映射。
我收到每个映射元素的以下错误消息
"error btm1044: Input validation error: The 'value' attribute is not declared."
我已经尝试按照单独 post 上的建议将 elementFormDefault 的值从不合格更改为合格,但仍然没有成功。
信封拆包后,我得到以下 XML。请注意,没有名称空间前缀。 如果我停止发送端口并查看分批处理的消息,则 MessageType 为 http://hl7.org/fhir/Encounters#Encounter .
<?xml version="1.0" encoding="utf-8"?>
<Encounter xmlns="http://hl7.org/fhir/Encounters">
<id value="ac34e2c2-6080-4c46-9ec5-d7340a7c4177" />
<extension url="https://api-foo.org/documents/fhir/extensions/encounter-facility">
<valueString value="foo" />
</extension>
<extension url="https://api-foo.org/documents/fhir/extensions/encounter-service">
<valueString value="fooo" />.......
我的架构如下所示
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://hl7.org/fhir/Encounters" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://hl7.org/fhir/Encounters" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Encounter">
<xs:complexType>
<xs:sequence>
<xs:element name="id">
<xs:complexType>
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="extension">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="valueInteger">
<xs:complexType>
<xs:attribute name="value" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="valueString">
<xs:complexType>
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="url" type="xs:string" use="required" />
</xs:complexType>
</xs:element> ............
有没有办法让 map/schema 按原样处理消息,或者有办法让分批处理的消息具有前缀。
我还有一个自定义管道组件,用于在分批处理之前更改传入消息的命名空间。我不确定这是否会导致下面的代码出现问题。
public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
{
if (Enabled)
{
try
{
IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart != null)
{
string json;
using (Stream originalDataStream = bodyPart.GetOriginalDataStream())
{
if (originalDataStream != null)
{
//Read the json message
using (TextReader tr = new StreamReader(originalDataStream))
{
json = tr.ReadToEnd();
}
//Use FHIR-NET-API to create a FHIR resource from the json
Hl7.Fhir.Serialization.ResourceReader resourceReader = new Hl7.Fhir.Serialization.ResourceReader(FhirJsonParser.CreateFhirReader(json), ParserSettings.Default);
//switch the namespace
var doc = XElement.Parse(Hl7.Fhir.Serialization.FhirSerializer.SerializeToXml(resourceReader.Deserialize()));
XNamespace toNs = Namespace;
doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
var ele = doc.DescendantsAndSelf();
foreach (var el in ele)
el.Name = toNs + el.Name.LocalName;
//Create the new BizTalk message
var memoryStream = new MemoryStream();
doc.Save(memoryStream);
// memoryStream.Write(resourceXmlBytes, 0, resourceXmlBytes.Length);
memoryStream.Position = 0;
inmsg.BodyPart.Data = memoryStream;
}
}
}
return inmsg;
}
catch (Exception e)
{
GenericEventLogger.LogEvent(
ExceptionSource,
String.Format("An exception [{0}] occured in [{1}( )]. \n\nMessage: \n{2} \n\nStack Trace: \n{3}",
e.GetType().Name,
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName,
e.Message,
e.StackTrace),
EventLogEntryType.Error,
999);
throw;
}
}
return inmsg;
}
这是信封架构
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://hl7.org/fhir/Encounters" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://hl7.org/fhir/Encounters" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:appinfo>
<b:schemaInfo is_envelope="yes" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" />
</xs:appinfo>
</xs:annotation>
<xs:element name="Bundle">
<xs:annotation>
<xs:appinfo>
<b:recordInfo body_xpath="/*[local-name()='Bundle' and namespace-uri()='http://hl7.org/fhir/Encounters']/*[local-name()='entry' and namespace-uri()='http://hl7.org/fhir/Encounters']/*[local-name()='resource' and namespace-uri()='http://hl7.org/fhir/Encounters']" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="total">
<xs:complexType>
<xs:attribute name="value" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="entry">
<xs:complexType>
<xs:sequence>
<xs:element name="resource">
<xs:complexType>
<xs:sequence>
<xs:element name="Encounter">
<xs:complexType>
<xs:sequence>
<xs:any />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
由于您使用的是 FHIR 的 JSON 表示,第一个问题应该是您是否需要使用 Xml 命名空间。
在 BizTalk 中处理本机 JSON 内容时,我的建议是在所有 Xml 处理中使用空命名空间。
您可以参考这篇维基文章了解更多详情:BizTalk: Simplify BizTalk Dev by Using the Empty Namespace