使用XSLT转换XML到XML,转换目标XML上的属性值

时间:2015-07-09 12:32:26

标签: xml xslt

我的源XML看起来像这样 -

目前XML如下所示:

<AllocInstrctn ID="108395820" TransTyp="1" AvgPx="0.35103" AvgParPx="0.35103">
<OrdAlloc ClOrdID="MANUAL" ClOrdID2="2634598" />
<Instrmt Fctr="1000" IssuCtry="ZA" />

转换后我希望它看起来像这样 -

<AllocInstrctn ID="108395820" TransTyp="1" AvgPx="351.03" AvgParPx="0.35103">
<OrdAlloc ClOrdID="MANUAL" ClOrdID2="2634598" />
<Instrmt Fctr="1" IssuCtry="ZA" />

所以基本上我们将AllocInstrctn标签中的AvgPX属性与Instrmt标签中的Fctr属性相乘,然后将Fctr值设为1.从未使用过XSLT。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,了解Identity Transform

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

使用这意味着您只需要为要转换的节点/属性编写模板。因此,在您的情况下,您需要一个模板来转换AvgPx属性

<xsl:template match="AllocInstrctn/@AvgPx">
    <xsl:attribute name="AvgPx">
        <xsl:value-of select="format-number(number() * number(../Instrmt/@Fctr), '0.00')" />
    </xsl:attribute>
</xsl:template>

您还需要一个(更简单的)模板来转换Fctr属性

<xsl:template match="Instrmt/@Fctr">
    <xsl:attribute name="AvgPx">
        <xsl:text>1</xsl:text>
    </xsl:attribute>
</xsl:template>

那就是它!试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="AllocInstrctn/@AvgPx">
        <xsl:attribute name="AvgPx">
            <xsl:value-of select="format-number(number() * number(../Instrmt/@Fctr), '0.00')" />
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="Instrmt/@Fctr">
        <xsl:attribute name="AvgPx">
            <xsl:text>1</xsl:text>
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

应用于此XML ...

<FIXML> 
<AllocInstrctn ID="108395820" TransTyp="1" AvgPx="0.35103" AvgParPx="0.35103">
<OrdAlloc ClOrdID="MANUAL" ClOrdID2="2634598" />
<Instrmt Fctr="1000" IssuCtry="ZA" />
</AllocInstrctn>
</FIXML>

以下是输出

<FIXML> 
   <AllocInstrctn ID="108395820" TransTyp="1" AvgPx="351.03" AvgParPx="0.35103">
      <OrdAlloc ClOrdID="MANUAL" ClOrdID2="2634598"/>
      <Instrmt AvgPx="1" IssuCtry="ZA"/>
   </AllocInstrctn>
</FIXML>

编辑:如果你的实际XML有名称空间,请尝试使用此XSLT。请注意开头的名称空间声明,并使用前缀(在本例中为f:)来匹配名称空间中的元素。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:f="fixprotocol.org/FIXML-4-4">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="f:AllocInstrctn/@AvgPx">
        <xsl:attribute name="AvgPx">
            <xsl:value-of select="format-number(number() * number(../f:Instrmt/@Fctr), '0.00')" />
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="f:Instrmt/@Fctr">
        <xsl:attribute name="AvgPx">
            <xsl:text>1</xsl:text>
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>