快速将调整应用于XML文件中的数据?

时间:2014-04-18 00:58:47

标签: xml

我有一个包含大量定义的XML文件,如下所示:

<skill name="zeal" type="attack" posture="defense">
    <stats level="1" attack_mult="0.60" dmg_mult="0.20" cooldown="65" num_attacks="1" radius="2.5" /> 
    <stats level="2" attack_mult="0.70" dmg_mult="0.24" cooldown="65" num_attacks="1" radius="2.5" />
    <stats level="3" attack_mult="0.80" dmg_mult="0.28" cooldown="65" num_attacks="1" radius="2.5" />
    <stats level="4" attack_mult="0.90" dmg_mult="0.32" cooldown="65" num_attacks="1" radius="2.5" />
    <stats level="5" attack_mult="1.00" dmg_mult="0.36" cooldown="65" num_attacks="1" radius="2.5" />
</skill>

现在我想调整我在该文件中的数据,而不是编辑每个单独的值本身。 例如:

  • 将所有dmg_mult属性乘以2(例如,dmg_mult =“0.20”中的make dmg_mult =“0.40”等)
  • 从现有级别推断出额外的级别。 (例如,看到attack_mult增加了0.10,dmg_mult增加了0.04,所以使用attack_mult 1.10和dmg_mult 0.40插入等级6)

如何有效地将这些“调整”应用于XML文件而不会浪费无数个小时?

1 个答案:

答案 0 :(得分:1)

您可以使用XSLT样式表将XML转换为另一个具有值乘法和外推(在某种程度上)的XML。 Xalan是一个免费的XSLT处理器来运行转换。

在我的示例中,推断相当简单,它取attack_multdmg_mult的最后两个属性值并确定差异,然后将其添加到最后一个属性的值以进行推断线性。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <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="skill">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <xsl:element name="stats">
        <xsl:attribute name="level">
          <xsl:value-of select="stats[last()]/@level+1"/>
        </xsl:attribute>
        <xsl:attribute name="attack_mult">
          <xsl:variable name="last_value" select="stats[last()]/@attack_mult"/>
          <xsl:value-of select="format-number($last_value + ($last_value - stats[last()-1]/@attack_mult), '0.00')"/>
        </xsl:attribute>
        <xsl:attribute name="dmg_mult">
          <xsl:variable name="last_value" select="stats[last()]/@dmg_mult*2"/>
          <xsl:value-of select="format-number($last_value + ($last_value - stats[last()-1]/@dmg_mult*2), '0.00')"/>
        </xsl:attribute>
        <xsl:attribute name="cooldown">
          <xsl:value-of select="stats[last()]/@cooldown"/>
        </xsl:attribute>
        <xsl:attribute name="num_attacks">
          <xsl:value-of select="stats[last()]/@num_attacks"/>
        </xsl:attribute>
        <xsl:attribute name="radius">
          <xsl:value-of select="stats[last()]/@radius"/>
        </xsl:attribute>
        </xsl:element>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="stats/@dmg_mult">
    <xsl:attribute name="dmg_mult">
      <xsl:value-of select=".*2"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

结果:

<?xml version="1.0" encoding="utf-8"?>
<skill name="zeal" type="attack" posture="defense">
  <stats level="1" attack_mult="0.60" dmg_mult="0.4" cooldown="65" num_attacks="1" radius="2.5" />
  <stats level="2" attack_mult="0.70" dmg_mult="0.48" cooldown="65" num_attacks="1" radius="2.5" />
  <stats level="3" attack_mult="0.80" dmg_mult="0.56" cooldown="65" num_attacks="1" radius="2.5" />
  <stats level="4" attack_mult="0.90" dmg_mult="0.64" cooldown="65" num_attacks="1" radius="2.5" />
  <stats level="5" attack_mult="1.00" dmg_mult="0.72" cooldown="65" num_attacks="1" radius="2.5" />
  <stats level="6" attack_mult="1.10" dmg_mult="0.80" cooldown="65" num_attacks="1" radius="2.5" />
</skill>