0

我有以下 xml 文件:

<xc:XmlCache xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot">
 <xc:XmlCacheArea xc:value="MarketParameters">
  <mp:nickName xc:value="MDS" xmlns:mp="mx.MarketParameters">
   <mp:date xc:value="20130315">
    <fx:forex xmlns:fx="mx.MarketParameters.Forex">
     <fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot">
      <fxsp:pair xc:value="AUD/AED" xc:type="Fields">
       <mp:ask xc:keyFormat="N">1.0000000</mp:ask> 
       <mp:bid xc:keyFormat="N">1.0000000</mp:bid> 
       <mp:formFactor xc:keyFormat="N">1</mp:formFactor> 
       <mp:high xc:keyFormat="N">0.0000000</mp:high> 
       <mp:low xc:keyFormat="N">0.0000000</mp:low> 
       <mp:mid xc:keyFormat="N">1.0000000</mp:mid> 
       <mp:quotation xc:keyFormat="C">AUD-AED</mp:quotation> 
      </fxsp:pair>
      <fxsp:pair xc:value="BHD/AED" xc:type="Fields">
       <mp:ask xc:keyFormat="N">0.8264463</mp:ask> 
       <mp:bid xc:keyFormat="N">0.8264463</mp:bid> 
       <mp:formFactor xc:keyFormat="N">1</mp:formFactor> 
       <mp:high xc:keyFormat="N">0.0000000</mp:high> 
       <mp:low xc:keyFormat="N">0.0000000</mp:low> 
       <mp:mid xc:keyFormat="N">0.8264463</mp:mid> 
       <mp:quotation xc:keyFormat="C">BHD-AED</mp:quotation> 
      </fxsp:pair>
     </fxsp:spot>
    </fx:forex>
   </mp:date>
  </mp:nickName>
 </xc:XmlCacheArea>
</xc:XmlCache>

我正在寻找一种方法来做两件事:1. 删除除两个之外的所有元素 -> mp:ask 和 mp:bid 2. 将这两个元素的数值更改为我在 csv 文件中拥有的其他值。

预期产出

<xc:XmlCache xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot">
<xc:XmlCacheArea xc:value="MarketParameters">
<mp:nickName xc:value="MDS" xmlns:mp="mx.MarketParameters">
<mp:date xc:value="20130315">
<fx:forex xmlns:fx="mx.MarketParameters.Forex">
<fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot">
<fxsp:pair xc:value="AUD/AED" xc:type="Fields">
<mp:ask xc:keyFormat="N">1.0000000</mp:ask> 
<mp:bid xc:keyFormat="N">1.0000000</mp:bid> 
</fxsp:pair>
<fxsp:pair xc:value="BHD/AED" xc:type="Fields">
<mp:ask xc:keyFormat="N">0.8264463</mp:ask> 
<mp:bid xc:keyFormat="N">0.8264463</mp:bid> 
</fxsp:pair>
</fxsp:spot>
</fx:forex>
</mp:date>
</mp:nickName>
</xc:XmlCacheArea>
</xc:XmlCache>

想法是用 csv 文件中提供的值更新输出 xml 中的值(第一个值是出价,第二个是询价)。如果需要,可以将 csv 文件转换为 xml,那没问题。

CSV file
AUD/AED;25;25
BHD/AED;20;20

该文件来自我们使用的应用程序。更改值后,目标是将文件重新导入应用程序。我在 xsl 中尝试了很多东西,但我必须说我不知道​​如何让它工作。

有人可以帮忙吗?

谢谢

4

1 回答 1

0

我建议您将 CSV 文件转换为 XML。XSLT 显然最适用于 XML。此外,您几乎肯定必须使用 XSLT 2.0 才有机会解析非 XML 文件。因此,出于此答案的目的,我假设查找文件如下所示

<csv>
   <record code="AUD/AED" bid="25" ask="25" />
   <record code="BHD/AED" bid="20" ask="20" />
</csv>

在进行转换方面,如果您还没有进行转换,那么您应该在 XSLT 身份转换的基础上复制所有现有节点作为开始。

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

这意味着您只需为要更改的节点/属性编写额外的模板。

你说你想删除除了'bid'和'ask'之外的所有(叶子)元素,好吧,你可以写一个这样的模板,忽略所有其他元素

<xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" />

您需要的唯一其他模板是与未排除的任何其他元素下的文本节点匹配的模板(即,它现在只会匹配您的“询问”和“出价”元素)

<xsl:template match="fxsp:pair/*/text()">

在此您可以从“查找”文件中进行查找

<xsl:value-of select="document('lookup.xml')//record[@code=$code]/@*[local-name()=$attr]"/>

在这种情况下,$code设置为来自fxsp:pair的xc:value的属性值,$attr是当前元素的名称('ask' 或 'bid')。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" />

  <xsl:template match="fxsp:pair/@xc:type" />

  <xsl:template match="fxsp:pair/*/text()">
    <xsl:variable name="code" select="../../@xc:value" />
    <xsl:variable name="attr" select="local-name(..)" />
    <xsl:value-of select="document('lookup.xml')//record[@code=$code]/@*[local-name()=$attr]"/>
  </xsl:template>
</xsl:stylesheet>

请注意,您可以将“文档”引用放在变量中,这可以简化事情(并且确实提高效率)。也试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:fx="mx.MarketParameters.Forex" xmlns:fxsp="mx.MarketParameters.Forex.Spot">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:variable name="lookup" select="document('lookup.xml')//record" />

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

  <xsl:template match="fxsp:pair/*[not(self::mp:ask) and not(self::mp:bid)]" />

  <xsl:template match="fxsp:pair/@xc:type" />

  <xsl:template match="fxsp:pair/*/text()">
    <xsl:variable name="code" select="../../@xc:value" />
    <xsl:variable name="attr" select="local-name(..)" />
    <xsl:value-of select="$lookup[@code=$code]/@*[local-name()=$attr]"/>
  </xsl:template>
</xsl:stylesheet>
于 2013-09-27T17:24:09.920 回答