也许有人有答案或想法。谢谢你。
这是为了在已部署的 Biztalk Server 应用程序中调试自定义 XSLT 映射。我遇到了错误,并且很难跟踪出了什么问题。顺便说一句,也许这里根本没有必要完全理解 Biztalk,因为我猜它主要是一个 XML、XSLT 相关问题。
因此,我回到了基础,从一个在已部署应用程序中工作的地图生成了一个非常简单的 XSLT,我希望直接在 Visual Studio 中以 XML 输出的形式直观地查看结果。从那里我想我可以试验我的自定义 XSLT 并比在部署的 Biztalk 应用程序中更容易地确定和修复错误(日志并不完全有帮助)。
所以在这里我所做的,如果有意义的话:(根据需要查看下面的代码 - 抱歉,我不得不稍微修剪一下代码以适应帖子)
在 Visual Studio 2012 Ultimate 中,
我有这个从功能 Biztalk 服务器映射(验证映射命令)生成的 XSLT。该地图的左侧(输入)有一个 Biztalk HL7 加速器 ADT_A01_25_GLO_DEF xsd 架构,右侧是我们的自定义输出架构;这是用于和传入的消息。
我从 ADT_A01_25_GLO_DEF xsd 模式生成了一个测试文件(生成实例命令)作为源 XML 文件来测试 XSLT;
我选择了那个 XML 文件作为 XSLT 的输入,以便在 VS 中处理;
我在没有调试的情况下使用菜单 XML / Start XSLT 中的命令处理该文件,Visual Studio 只给了我一个错误:
XML 文档必须包含根级元素。
(输出文件实际上是空的)
请知道我缺少什么吗?
谢谢
克劳德
左侧的 Biztalk 加速器 Hl7 ADT_A01_25_GLO_DEF xsd 架构:
<?xml version="1.0" encoding="utf-16" ?>
- <xs:schema xmlns="http://microsoft.com/HealthCare/HL7/2X" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:ns0="http://microsoft.com/HealthCare/HL7/2X/2.5/Segments" targetNamespace="http://microsoft.com/HealthCare/HL7/2X" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="BTAHL7Schemas.segments_25" namespace="http://microsoft.com/HealthCare/HL7/2X/2.5/Segments" />
- <xs:annotation>
- <xs:appinfo>
<b:schemaInfo standards_version="HL7.DBVersion.1_5" document_type="HL7 2X Schema" version="2.0.0104.0.2.0" root_reference="ADT_A01_25_GLO_DEF" />
- <b:references>
<b:reference targetNamespace="http://microsoft.com/HealthCare/HL7/2X/2.5/DataTypes" />
<b:reference targetNamespace="http://microsoft.com/HealthCare/HL7/2X/2.5/Segments" />
<b:reference targetNamespace="http://microsoft.com/HealthCare/HL7/2X/2.5/Tables" />
</b:references>
</xs:appinfo>
</xs:annotation>
- <xs:element name="ADT_A01_25_GLO_DEF">
- <xs:complexType>
- <xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="SFT_SoftwareSegment" type="ns0:SFT" />
<xs:element minOccurs="1" maxOccurs="1" name="EVN_EventType" type="ns0:EVN" />
<xs:element minOccurs="1" maxOccurs="1" name="PID_PatientIdentification" type="ns0:PID" />
<xs:element minOccurs="0" maxOccurs="1" name="PD1_PatientAdditionalDemographic" type="ns0:PD1" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="ROL_Role" type="ns0:ROL" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="NK1_NextOfKinAssociatedParties" type="ns0:NK1" />
<xs:element minOccurs="1" maxOccurs="1" name="PV1_PatientVisit" type="ns0:PV1" />
<xs:element minOccurs="0" maxOccurs="1" name="PV2_PatientVisitAdditionalInformation" type="ns0:PV2" />
....snip....
<xs:element minOccurs="0" maxOccurs="1" name="PDA_PatientDeathAndAutopsy" type="ns0:PDA" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在 Visusal Studio 中从模式生成的 XML 实例,经过修剪,带有一些数据
<?xml version="1.0" encoding="utf-16" ?>
<root>
<PID_PatientIdentification>
<PID_1_SetIdPid>PID_1_SetIdPid_0</PID_1_SetIdPid>
....snip....
<PID_3_PatientIdentifierList>
<CX_0_IdNumber>1</CX_0_IdNumber>
<CX_1_CheckDigit>CX_1_CheckDigit_0</CX_1_CheckDigit>
<CX_2_CheckDigitScheme>CX_2_CheckDigitScheme_0</CX_2_CheckDigitScheme>
<CX_3_AssigningAuthority>
<CX_3_0_NamespaceId>CX_3_0_NamespaceId_0</CX_3_0_NamespaceId>
<CX_3_1_UniversalId>CX_3_1_UniversalId_0</CX_3_1_UniversalId>
<CX_3_2_UniversalIdType>CX_3_2_UniversalIdType_0</CX_3_2_UniversalIdType>
</CX_3_AssigningAuthority>
<CX_4_IdentifierTypeCode>SSN</CX_4_IdentifierTypeCode>
<CX_5_AssigningFacility>
<CX_5_0_NamespaceId>CX_5_0_NamespaceId_0</CX_5_0_NamespaceId>
<CX_5_1_UniversalId>CX_5_1_UniversalId_0</CX_5_1_UniversalId>
<CX_5_2_UniversalIdType>CX_5_2_UniversalIdType_0</CX_5_2_UniversalIdType>
</CX_5_AssigningFacility>
<CX_6_EffectiveDate>CX_6_EffectiveDate_0</CX_6_EffectiveDate>
<CX_7_ExpirationDate>CX_7_ExpirationDate_0</CX_7_ExpirationDate>
<CX_8_AssigningJurisdiction>
<CX_8_0_Identifier>CX_8_0_Identifier_0</CX_8_0_Identifier>
<CX_8_1_Text>CX_8_1_Text_0</CX_8_1_Text>
<CX_8_2_NameOfCodingSystem>CX_8_2_NameOfCodingSystem_0</CX_8_2_NameOfCodingSystem>
<CX_8_3_AlternateIdentifier>CX_8_3_AlternateIdentifier_0</CX_8_3_AlternateIdentifier>
<CX_8_4_AlternateText>CX_8_4_AlternateText_0</CX_8_4_AlternateText>
....snip....
</PID_PatientIdentification>
....snip....
</root>
从工作 Biztalk 映射生成的 XSLT:
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 s1 s2 s3 s4 userCSharp"
version="1.0"
xmlns:s0="http://schemas.microsoft.com/BizTalk/2003/aggschema"
xmlns:s1="http://microsoft.com/HealthCare/HL7/2X/2.5/Tables"
xmlns:s2="http://microsoft.com/HealthCare/HL7/2X"
xmlns:s3="http://microsoft.com/HealthCare/HL7/2X/2.5/Segments"
xmlns:s4="http://microsoft.com/HealthCare/HL7/2X/2.5/DataTypes"
xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="/s0:Root" />
</xsl:template>
<xsl:template match="/s0:Root">
<form1>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.3_SendingApplication/HD.0_NamespaceId">
<MSH_3-SendingApplication>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.3_SendingApplication/HD.0_NamespaceId/text()" />
</MSH_3-SendingApplication>
</xsl:if>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.4_SendingFacility/HD.0_NamespaceId">
<MSH_4-SendingFacility>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.4_SendingFacility/HD.0_NamespaceId/text()" />
</MSH_4-SendingFacility>
</xsl:if>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.5_ReceivingApplication/HD.0_NamespaceId">
<MSH_5-ReceiveApplication>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.5_ReceivingApplication/HD.0_NamespaceId/text()" />
</MSH_5-ReceiveApplication>
</xsl:if>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.6_ReceivingFacility/HD.0_NamespaceId">
<MSH_6-ReceiveFacility>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.6_ReceivingFacility/HD.0_NamespaceId/text()" />
</MSH_6-ReceiveFacility>
</xsl:if>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.9_MessageType/CM_MSG.0_MessageType">
<MSH_9-MessageType>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.9_MessageType/CM_MSG.0_MessageType/text()" />
</MSH_9-MessageType>
</xsl:if>
<xsl:if test="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.9_MessageType/CM_MSG.1_TriggerEvent">
<MSH_9-EventTrigger>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.9_MessageType/CM_MSG.1_TriggerEvent/text()" />
</MSH_9-EventTrigger>
</xsl:if>
<MSH_10-MessageControlID>
<xsl:value-of select="InputMessagePart_0/s2:MSH_25_GLO_DEF/MSH/MSH.10_MessageControlId/text()" />
</MSH_10-MessageControlID>
<xsl:variable name="var:v1" select="userCSharp:MyConcat()" />
<EventTimeStamp>
<xsl:value-of select="$var:v1" />
</EventTimeStamp>
<xsl:variable name="var:v2" select="userCSharp:TSTime()" />
<PID_33-ApplicationDate>
<xsl:value-of select="$var:v2" />
</PID_33-ApplicationDate>
<xsl:for-each select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_3_PatientIdentifierList">
<PID_3_PatientIdentifierList>
<xsl:if test="CX_0_IdNumber">
<IdNumber>
<xsl:value-of select="CX_0_IdNumber/text()" />
</IdNumber>
</xsl:if>
<xsl:if test="CX_4_IdentifierTypeCode">
<IdentifierTypeCode>
<xsl:value-of select="CX_4_IdentifierTypeCode/text()" />
</IdentifierTypeCode>
</xsl:if>
</PID_3_PatientIdentifierList>
</xsl:for-each>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_5_PatientName/XPN_0_FamilyName/XPN_0_0_Surname">
<PID_5-LastName>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_5_PatientName/XPN_0_FamilyName/XPN_0_0_Surname/text()" />
</PID_5-LastName>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_5_PatientName/XPN_1_GivenName">
<PID_5-FirstName>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_5_PatientName/XPN_1_GivenName/text()" />
</PID_5-FirstName>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_7_DateTimeOfBirth/TS_0_Time">
<PID_7-BirthDate>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_7_DateTimeOfBirth/TS_0_Time/text()" />
</PID_7-BirthDate>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_15_PrimaryLanguage/CE_0_Identifier">
<PID_15-PreferredLanguage>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_15_PrimaryLanguage/CE_0_Identifier/text()" />
</PID_15-PreferredLanguage>
</xsl:if>
<xsl:variable name="var:v3" select="userCSharp:ConvertSex(string(InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_8_AdministrativeSex/text()))" />
<PID_8-Sex>
<xsl:value-of select="$var:v3" />
</PID_8-Sex>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_13_PhoneNumberHome/XTN_0_TelephoneNumber">
<PID_13-HomePhone>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_13_PhoneNumberHome/XTN_0_TelephoneNumber/text()" />
</PID_13-HomePhone>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_14_PhoneNumberBusiness/XTN_0_TelephoneNumber">
<PID_14-WorkPhone>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_14_PhoneNumberBusiness/XTN_0_TelephoneNumber/text()" />
</PID_14-WorkPhone>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_0_StreetAddress/XAD_0_0_StreetOrMailingAddress">
<PID_11-Address>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_0_StreetAddress/XAD_0_0_StreetOrMailingAddress/text()" />
</PID_11-Address>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_2_City">
<PID_11-City>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_2_City/text()" />
</PID_11-City>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_3_StateOrProvince">
<PID_11-IDState>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_3_StateOrProvince/text()" />
</PID_11-IDState>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_4_ZipOrPostalCode">
<PID_11-ZIPCode>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_11_PatientAddress/XAD_4_ZipOrPostalCode/text()" />
</PID_11-ZIPCode>
</xsl:if>
<xsl:if test="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_13_PhoneNumberHome/XTN_3_EmailAddress">
<Email>
<xsl:value-of select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/PID_PatientIdentification/PID_13_PhoneNumberHome/XTN_3_EmailAddress/text()" />
</Email>
</xsl:if>
<xsl:for-each select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/NK1_NextOfKinAssociatedParties">
<xsl:for-each select="NK1_2_Name">
<xsl:for-each select="XPN_0_FamilyName">
<Nk1>
<NK1_1-SetID>
<xsl:value-of select="../../NK1_1_SetIdNk1/text()" />
</NK1_1-SetID>
<NK1_2-DelegateLastName>
<xsl:value-of select="./text()" />
</NK1_2-DelegateLastName>
<xsl:if test="../XPN_1_GivenName">
<NK1_2-DelegateFirstName>
<xsl:value-of select="../XPN_1_GivenName/text()" />
</NK1_2-DelegateFirstName>
</xsl:if>
<xsl:if test="../../NK1_3_Relationship/CE_0_Identifier">
<NK1_3-IDDelegateRelationship>
<xsl:value-of select="../../NK1_3_Relationship/CE_0_Identifier/text()" />
</NK1_3-IDDelegateRelationship>
</xsl:if>
<xsl:if test="../../NK1_5_PhoneNumber/XTN_0_TelephoneNumber">
<NK1_5-DelegateHomePhone>
<xsl:value-of select="../../NK1_5_PhoneNumber/XTN_0_TelephoneNumber/text()" />
</NK1_5-DelegateHomePhone>
</xsl:if>
<xsl:if test="../../NK1_5_PhoneNumber/XTN_3_EmailAddress">
<NK1_5-DelegateEmail>
<xsl:value-of select="../../NK1_5_PhoneNumber/XTN_3_EmailAddress/text()" />
</NK1_5-DelegateEmail>
</xsl:if>
<xsl:if test="../../NK1_6_BusinessPhoneNumber/XTN_0_TelephoneNumber">
<NK1_6-DelegateWorkPhone>
<xsl:value-of select="../../NK1_6_BusinessPhoneNumber/XTN_0_TelephoneNumber/text()" />
</NK1_6-DelegateWorkPhone>
</xsl:if>
</Nk1>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/AL1_PatientAllergyInformation">
<AL1_PatientAllergy>
<AL1_1-SetID>
<xsl:value-of select="AL1_1_SetIdAl1/text()" />
</AL1_1-SetID>
<xsl:if test="AL1_2_AllergenTypeCode/CE_0_Identifier">
<AL1_2-AllergenTypeCode>
<xsl:value-of select="AL1_2_AllergenTypeCode/CE_0_Identifier/text()" />
</AL1_2-AllergenTypeCode>
</xsl:if>
<xsl:if test="AL1_3_AllergenCodeMnemonicDescription/CE_0_Identifier">
<AL1_3-AllergyDescription>
<xsl:value-of select="AL1_3_AllergenCodeMnemonicDescription/CE_0_Identifier/text()" />
</AL1_3-AllergyDescription>
</xsl:if>
<xsl:if test="AL1_4_AllergySeverityCode/CE_0_Identifier">
<AL1_4-Severity>
<xsl:value-of select="AL1_4_AllergySeverityCode/CE_0_Identifier/text()" />
</AL1_4-Severity>
</xsl:if>
</AL1_PatientAllergy>
</xsl:for-each>
<xsl:for-each select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/OBX_ObservationResult">
<xsl:for-each select="OBX_5_ObservationValue">
<OBX_ObservationResult>
<xsl:if test="../OBX_1_SetIdObx">
<OBX_1_SetIDObx>
<xsl:value-of select="../OBX_1_SetIdObx/text()" />
</OBX_1_SetIDObx>
</xsl:if>
<xsl:if test="../OBX_2_ValueType">
<OBX_2_ValueType>
<xsl:value-of select="../OBX_2_ValueType/text()" />
</OBX_2_ValueType>
</xsl:if>
<xsl:if test="../OBX_3_ObservationIdentifier/CE_0_Identifier">
<OBX_3_ObservationIdentifier>
<xsl:value-of select="../OBX_3_ObservationIdentifier/CE_0_Identifier/text()" />
</OBX_3_ObservationIdentifier>
</xsl:if>
<xsl:if test="../OBX_3_ObservationIdentifier/CE_1_Text">
<OBX_3_Text>
<xsl:value-of select="../OBX_3_ObservationIdentifier/CE_1_Text/text()" />
</OBX_3_Text>
</xsl:if>
<OBX_5_ObservationValue>
<xsl:value-of select="./text()" />
</OBX_5_ObservationValue>
<xsl:if test="../OBX_6_Units/CE_1_Text">
<OBX_6_Units>
<xsl:value-of select="../OBX_6_Units/CE_1_Text/text()" />
</OBX_6_Units>
</xsl:if>
<OBX_11_ObservationResultStatus>
<xsl:value-of select="../OBX_11_ObservationResultStatus/text()" />
</OBX_11_ObservationResultStatus>
<xsl:if test="../OBX_14_DateTimeOfTheObservation">
<OBX_14_DataTimeOfTheObservation>
<xsl:value-of select="../OBX_14_DateTimeOfTheObservation/text()" />
</OBX_14_DataTimeOfTheObservation>
</xsl:if>
</OBX_ObservationResult>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="InputMessagePart_1/s2:ADT_A01_25_GLO_DEF/DG1_Diagnosis">
<xsl:for-each select="DG1_3_DiagnosisCodeDg1">
<DG1_Diagnosis>
<xsl:if test="CE_0_Identifier">
<DG1_3_DiagnosisCodeDG1>
<xsl:value-of select="CE_0_Identifier/text()" />
</DG1_3_DiagnosisCodeDG1>
</xsl:if>
<xsl:if test="../DG1_4_DiagnosisDescription">
<DG1_4_DiagnosisDescription>
<xsl:value-of select="../DG1_4_DiagnosisDescription/text()" />
</DG1_4_DiagnosisDescription>
</xsl:if>
<xsl:if test="../DG1_5_DiagnosisDateTime/TS_0_Time">
<DG1_5_DiagnosticDateTime>
<xsl:value-of select="../DG1_5_DiagnosisDateTime/TS_0_Time/text()" />
</DG1_5_DiagnosticDateTime>
</xsl:if>
<DG1_6_DiagnosticType>
<xsl:value-of select="../DG1_6_DiagnosisType/text()" />
</DG1_6_DiagnosticType>
</DG1_Diagnosis>
</xsl:for-each>
</xsl:for-each>
</form1>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string ConvertSex(string sex)
{
if (sex == "F")
return "Female";
else
return "Male";
}
public string TSTime ()
{
DateTime now = DateTime.Now;
string ts = now.ToString("yyyyMMddHHmm");
return ts;
}
public string MyConcat()
{
DateTime now = DateTime.Now;
string ts = now.ToString("yyyyMMddHHmm");
return ts;
}
]]></msxsl:script>
</xsl:stylesheet>