2

我有一个非常复杂的输入消息,我需要将其节点名称和值(没有任何命名空间信息)反刍到输出中,就像使用 XSL 样式表在浏览器中查看文档一样。我不需要将任何单独的源 XML 元素映射到相应的目标元素。输出将被传递给平面文件汇编器,并作为简单的文本消息发送给消费者。

为简单起见,我删除了此样式表中的大部分命名空间并更改了前缀,从而产生了我想要的输出:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:abcd="http://abcd.whatever.net/abcd/1.0.1" xmlns:info="http://info.sumthin.net/1.0.0" xmlns:wxyz="http://wxyz.widgetwonks.net/wxyz/3.0.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<xsl:output method="text" />

<xsl:template match="abcd:Message">
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="info:SpecialText">
    <xsl:text> </xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>&#010;</xsl:text>
</xsl:template>

<xsl:template match="wxyz:PersonSSN">
    <xsl:text> SSN: </xsl:text>
    <xsl:value-of select="substring(., 0, 4)"/>
    <xsl:text>-</xsl:text>
    <xsl:value-of select="substring(., 4, 2)"/>
    <xsl:text>-</xsl:text>
    <xsl:value-of select="substring(., 6, 4)"/>
    <xsl:text>&#010;</xsl:text>
</xsl:template>

<xsl:template match="*">
    <xsl:if test="string-length(normalize-space(text()))=0">
        <xsl:text>&#010;</xsl:text>
        <xsl:value-of select="local-name()"/>
    <xsl:text>&#010;</xsl:text>
    </xsl:if>

    <xsl:if test="not(string-length(normalize-space(text()))=0)">
        <xsl:text> </xsl:text>
        <xsl:value-of select="local-name()"/>: <xsl:value-of select="normalize-space(text())"/>
    </xsl:if>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
    <xsl:if test="string-length(normalize-space(.)) != 0">
        <xsl:text>&#010;</xsl:text>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

在 BizTalk 中,我在地图网格的“自定义 XSL 路径”属性中引用了这个样式表,当我测试地图时,我得到了正确的输出。

但是如何将此输出映射到目标模式? 样式表的输出只是一个很长的文本流,其中散布着许多 x0D x0A (cr / lf)。我无法设计出 BizTalk 允许作为样式表输出容器的模式。

-标记

4

2 回答 2

2

我终于解决了我自己的问题,如下。

开发了以下 XSL 样式表来将输入消息转换为普通的 XML 文档:

<?xml version="1.0" encoding="utf-8"?>
<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 ScriptNS0" version="1.0" xmlns:s0="http://abcd.whatever.net/abcd/1.0.1" xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0" xmlns:info="http://info.sumthin.net/1.0.0" xmlns:wxyz="http://wxyz.widgetwonks.net/wxyz/3.0.3">

<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />

<xsl:template match="/">
    <Message>
        <xsl:apply-templates />
    </Message>
</xsl:template>
<!-- <xsl:template match="/s0:Message" /> -->
<xsl:template match="info:CaveatText">
    <xsl:element name="TextField">
        <xsl:text>  </xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>&#010;</xsl:text>
    </xsl:element>
</xsl:template>

<xsl:template match="wxyz:PersonSSNID/wxyz:ID">
    <xsl:element name="TextField">
        <xsl:text>    SSN: </xsl:text>
        <xsl:value-of select="substring(., 0, 4)"/>
        <xsl:text>-</xsl:text>
        <xsl:value-of select="substring(., 4, 2)"/>
        <xsl:text>-</xsl:text>
        <xsl:value-of select="substring(., 6, 4)"/>
        <xsl:text>&#010;</xsl:text>
    </xsl:element>
</xsl:template>

<xsl:template match="*">
    <xsl:if test="string-length(normalize-space(text()))=0">
        <xsl:element name="TextField">
            <xsl:text>&#010;</xsl:text>
            <xsl:value-of select="local-name()"/>
            <xsl:text>&#010;</xsl:text>
        </xsl:element>
    </xsl:if>

    <xsl:if test="not(string-length(normalize-space(text()))=0)">
        <xsl:element name="TextField">
            <xsl:text>    </xsl:text>
            <xsl:value-of select="local-name()"/>: <xsl:value-of select="normalize-space(text())"/>
        </xsl:element>
    </xsl:if>
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
    <xsl:if test="string-length(normalize-space(.)) != 0">
        <xsl:element name="TextField">
            <xsl:text>&#010;</xsl:text>
        </xsl:element>
    </xsl:if>
</xsl:template>

由样式表创建的示例 XML 文档在文本编辑器中如下所示:

<Message xmlns:{namespaces galore...}><TextField>
Message
</TextField><TextField>
HeaderArea
</TextField><TextField>    KeyText: PQ</TextField><TextField>
</TextField><TextField>    HeaderText: XYXY1010Z</TextField><TextField>
</TextField><TextField>
ResponseDataSection
</TextField><TextField>  **TEST**THIS RESPONSE IS FROM ABCD TEST SYSTEM.
</TextField><TextField>
PersonName
</TextField><TextField>    PersonGivenName: JACK</TextField><TextField>
</TextField><TextField>    PersonMiddleName: DANIEL</TextField><TextField>
</TextField><TextField>    PersonSurName: WEBBER</TextField><TextField>
</TextField><TextField>    PersonBirthDateText: 1975-01-31</TextField><TextField>
</TextField><TextField>
PersonAssignedIDDetails
</TextField><TextField>
PersonSSNID
</TextField><TextField>    SSN: 123-98-7654
</TextField><TextField>
PersonOtherID
</TextField><TextField>    ID: XT-01020304050</TextField><TextField>
</TextField><TextField>
PersonPhysicalDetails
</TextField><TextField>    PersonSexCode: M</TextField><TextField>
</TextField><TextField>    PersonRaceCode: W</TextField><TextField>
</TextField><TextField>
PersonAbcdID
</TextField><TextField>    ID: Z123456789</TextField><TextField>
</TextField><TextField>    ExpandedBirthDateSearch: 1</TextField><TextField>
</TextField><TextField>    ExpandedNameSearchIndicator: false</TextField><TextField>
</TextField><TextField>
VehicleID
</TextField><TextField>    ID: ASDFASDFASDFASDFA</TextField><TextField>
</TextField><TextField>    VehicleMakeText: DODG</TextField><TextField>
</TextField><TextField>
VehicleRegistrationPlateID
</TextField><TextField>    ID: ABC123</TextField><TextField>
</TextField><TextField>    IDJurisdictionText: AZ</TextField><TextField>
</TextField><TextField>
PrimaryResponse
</TextField><TextField>
PersonAlias
</TextField><TextField>
PersonAlternateName
</TextField><TextField>    PersonGivenName: JACK</TextField><TextField>
</TextField><TextField>    PersonMiddleName: ALLEN</TextField><TextField>
</TextField><TextField>    PersonSurName: DANIEL</TextField><TextField>
</TextField><TextField>
PersonAlternateName
</TextField><TextField>    PersonGivenName: JACKIE</TextField><TextField>
</TextField><TextField>    PersonSurName: DANIEL</TextField><TextField>
</TextField><TextField>
PersonAlternateName
</TextField><TextField>    PersonGivenName: JD</TextField><TextField>
</TextField><TextField>    PersonSurName: DANIEL</TextField><TextField>
</TextField><TextField>    PersonBirthDateText: 1967-01-01</TextField><TextField>
</TextField><TextField>    PersonBirthDateText: 1968-01-01</TextField><TextField>
</TextField><TextField>
PersonAssignedIDDetails
</TextField><TextField>
PersonSSNID
</TextField><TextField>    SSN: 234-00-0001
</TextField><TextField>
PersonSSNID
</TextField><TextField>    SSN: 345-00-0002
</TextField><TextField>
PersonSSNID
</TextField><TextField>    SSN: 456-00-0003
</TextField><TextField>
PersonSSNID
</TextField><TextField>    SSN: 567-00-0004
</TextField><TextField>
PersonOtherID
</TextField><TextField>    ID: XZ1234DE</TextField><TextField>
</TextField><TextField>
PersonOtherID
</TextField><TextField>    ID: YZE6241</TextField><TextField>
</TextField><TextField>
</Message>

在上面, (...break to next line...) 序列是由样式表的片段生成的 CR/LF。

上面消息的架构很简单:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:xsi={application-specific namespace} xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:annotation>
    <xs:appinfo>
      <schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
      <b:schemaInfo root_reference="Message" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" standard="Flat File" />
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Message">
    <xs:annotation>
      <xs:appinfo>
        <b:recordInfo structure="delimited" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" sequence_number="1" />
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:annotation>
          <xs:appinfo>
            <b:groupInfo sequence_number="0" />
          </xs:appinfo>
        </xs:annotation>
        <xs:element maxOccurs="unbounded" name="TextField" type="xs:string">
          <xs:annotation>
            <xs:appinfo>
              <b:fieldInfo sequence_number="1" justification="left" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

在 Visual Studio 中,架构编辑器树显示了架构的真正简单程度:

<Schema>                (Schema Editor Extensions is set to Flat File Extension)
    Message         (a record with no default properties)
        TextString      (a child element defined as unbounded)

BizTalk 映射: 1. 映射上没有 functoid,因为它将使用自定义 XSLT 文件使用上述目标架构生成消息。2. 使用 Validate Map,生成自定义扩展 XML 文件。3. 将自定义扩展 XML 和我的样式表文件添加到项目中。4. 在地图设计图面上,通过导航到刚才提到的文件来设置自定义扩展 XML 和自定义 XSL 路径属性。

创建了一个 BizTalk 管道,其中包括使用目标架构的平面文件汇编器。

部署解决方案。

将发送端口配置为使用新的发送管道。

最终输出是一个平面文件,如下所示:

Message

HeaderArea
    TransactionKeyText: PQ
    TransactionHeaderText: XYXY1010Z

ResponseDataSection
  **TEST**THIS RESPONSE IS FROM ABCD TEST SYSTEM.

PersonName
    PersonGivenName: JACK
    PersonMiddleName: DANIEL
    PersonSurName: WEBBER
    PersonBirthDateText: 1975-01-31

PersonAssignedIDDetails

PersonSSNID
    SSN: 123-98-7654

PersonOtherID
    ID: XT-01020304050

PersonPhysicalDetails
    PersonSexCode: M
    PersonRaceCode: W

PersonAbcdID
    ID: Z123456789
    ExpandedBirthDateSearch: 1
    ExpandedNameSearchIndicator: false

VehicleID
    ID: ASDFASDFASDFASDFA
    VehicleMakeText: DODG

VehicleRegistrationPlateID
    ID: ABC123
    IDJurisdictionText: AZ

PrimaryResponse

PersonAlias

PersonAlternateName
    PersonGivenName: JACK
    PersonMiddleName: ALLEN
    PersonSurName: DANIEL

PersonAlternateName
    PersonGivenName: JACKIE
    PersonSurName: DANIEL

PersonAlternateName
    PersonGivenName: JD
    PersonSurName: DANIEL
    PersonBirthDateText: 1967-01-01
    PersonBirthDateText: 1968-01-01

PersonAssignedIDDetails

PersonSSNID
    SSN: 234-00-0001

PersonSSNID
    SSN: 345-00-0002

PersonSSNID
    SSN: 456-00-0003

PersonSSNID
    SSN: 567-00-0004

PersonOtherID
    ID: XZ1234DE

PersonOtherID
    ID: YZE6241
于 2012-07-11T21:08:49.200 回答
0

使用单个字符串元素定义输出模式。然后修改您的 xsl 转换以将您的输出包装在CDATA部分中。您的输出将与此类似:

<?xml version="1.0" encoding="utf-8"?>
<MyOutputSchema>
<MyOutputString>
<![CDATA[<sender>Your output goes here</sender>]]>
</output-junk-drawer>
</MyOutputString>

CDATA 将允许在 xml 消息中放置无效字符。然后您可以使用 BizTalk 处理输出。

于 2012-07-10T19:45:52.547 回答