需要使用XSLT从XML的平面文件中定制订单

时间:2013-05-14 18:41:49

标签: java xslt flat-file xalan edi

我想使用xslt从xml创建一个平面文件,其输出顺序如下所示:

NM1 * CC * 1 * *史密斯约翰**** 34 * 999999999〜
N3 * 100大街〜

从这个XML:

<Claim>
 <Claimant
    lastName="Smith"
    firstName="John"
    middleName=""
    suffixName=""
    indentificationCodeQualifier="34"
    identificationCode="999999999">
    <ClaimantStreetLocation
        primary="100 Main Street"
        secondary=""/>
 </Claimant>
</Claim>

使用我创建的XSLT,我得到了相反的所需顺序的输出,如下所示,因为XSLT在遍历我假设的输入树时的工作性质如下:

N3 * 100 Main Street~
NM1 * CC * 1 * *史密斯约翰**** 34 * 999999999〜

我需要更改/添加什么来获取我正在寻找的XSLT的订单,如下所示: `          

<xsl:template match="Claim/Claimant">
    <xsl:apply-templates />
    <xsl:text>NM1*CC*1*</xsl:text>
    <xsl:value-of select="@lastName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@firstName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@middleName" />
    <xsl:text>*</xsl:text>
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@suffixName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@indentificationCodeQualifier" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@identificationCode" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>

<xsl:template match="Claim/Claimant/ClaimantStreetLocation">
    <xsl:apply-templates />
    <xsl:text>N3*</xsl:text>
    <xsl:value-of select="@primary" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>`

如果没有将两个标签合并为一个,有没有办法做到这一点?

任何反馈都将不胜感激。

我不知道它是否重要,但我正在使用xalan-java来处理代码中的xslt。

1 个答案:

答案 0 :(得分:2)

如果要在子项之前处理父项,则应将apply-templates移动到父模板的末尾:

<xsl:template match="Claim/Claimant">
    <xsl:text>NM1*CC*1*</xsl:text>
    <xsl:value-of select="@lastName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@firstName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@middleName" />
    <xsl:text>*</xsl:text>
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@suffixName" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@indentificationCodeQualifier" />
    <xsl:text>*</xsl:text>
    <xsl:value-of select="@identificationCode" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="ClaimantStreetLocation">
    <xsl:apply-templates />
    <xsl:text>N3*</xsl:text>
    <xsl:value-of select="@primary" />
    <xsl:text>~</xsl:text>
    <xsl:text>
    </xsl:text>
</xsl:template>`

更新:这里发生的事情是:

  1. 处理的第一个元素是Claim,但没有与之匹配的模板,因此应用默认模板,该模板处理其子节点的模板。

  2. 在那里,第一个孩子是Claimant,你有一个匹配它的模板,所以它被应用了。

  3. 接下来,按顺序处理该模板。但关键的一点是apply-templates忽略了默认选择中的属性(参见 What is the default select of XSLT apply-templates?),因此唯一匹配的节点是ClaimantStreetLocation元素。

  4. 鉴于您有一个与ClaimantStreetLocation匹配的模板,它将被应用。因此,如果您想首先处理属性,则应该延迟apply-templates,直到它们被选中为止。