【问题标题】:Transform XML to XML using XSLT transforming attribute values on target XML使用 XSLT 转换目标 XML 上的属性值将 XML 转换为 XML
【发布时间】:2015-07-09 12:32:25
【问题描述】:

我的源 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。任何帮助将不胜感激。

【问题讨论】:

  • AllocInstrctn 是根元素吗?它没有结束标签。
  • Sorry the structure is 所以 FIXML 是 root,AllocInstrctn 包含在其中,其他两个元素包含在 AllocInstrCtn 中

标签: xml xslt


【解决方案1】:

首先,了解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>

【讨论】:

  • 非常感谢。我会试试的。非常感谢
  • 一个快速的问题。它适用于上面的代码,但是我的 FIXML 根标签的属性很少,如下所示。当我添加它们时,输出的 XML 与没有转换(乘法)的输入相同。 w3.org/2001/XMLSchema" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns="fixprotocol.org/FIXML-4-4">
  • 在身份模板之后,您需要了解的下一件事是命名空间。 “xmlns”不是属性。它是一个命名空间声明。例如,请参阅xml.com/pub/a/2001/04/04/trxml
  • 我已经修改了我的答案以应对命名空间。如果您确实花时间在 XML/XSLT 上,那么学习名称空间将非常有益。谢谢!
  • 太棒了。非常感谢蒂姆。
猜你喜欢
  • 1970-01-01
  • 2010-10-13
  • 2017-12-25
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多