【问题标题】:Need custom order in flat file from XML using XSLT需要使用 XSLT 从 XML 的平面文件中自定义订单
【发布时间】:2013-05-09 03:56:35
【问题描述】:

我想使用 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 大街~
NM1*CC*1*史密斯*约翰****34*999999999~

我需要更改/添加什么来获得我正在寻找的 XSLT 的订单,我编写的 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。

【问题讨论】:

    标签: java xslt flat-file xalan edi


    【解决方案1】:

    如果你想在子级之前处理父级,你应该将 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 匹配的模板,它会被应用。因此,如果您想首先处理属性,您应该延迟应用模板,直到它们被选中,在您的情况下,手动选择。

    【讨论】:

    • 谢谢你!那行得通。但是如何将 移动到父级的底部导致父级首先运行。如果我需要在 ClaimantStreetLocation 模板之后添加一个新行,我应该命名这些 标记吗?
    • 为答案添加了解释。希望对您有所帮助。
    • 这是有道理的。谢谢你的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多