在转换之前是否存在转换值的干燥方法?

时间:2012-07-18 03:58:40

标签: xslt

假设我有以下xml。

<root>
  <data>
    <a>ATTITUDE_ANNOYED</a>
    <b>ATTITUDE_CAUTIOUS</b>
    <c>25</c>
    <d>30</d>
  </data>
</root>

忽略输出的模式,我希望我的输出将A显示为“谨慎”(从恼火中提升一级),B为“ 高兴“(从Cautious一级以上),我想在C和D上执行一些数学运算,将价值转换为稍微不同的值。

我在这里看过一堆类似的问题(我是XSLT的新手,所以也许我不太了解它)但很多解决方案看起来都是“在线”,即在转换结果时修改结果。这没关系,但在我的实例中有很多这些值,我不想在多个地方(DRY)执行完全相同的转换。在开始转换之前,我只想或多或少地预处理整个文档并将一堆值转换为其他值(仅使用几个公式)。

实现这一目标的最佳方法是什么?我对性能不是特别感兴趣,那么有没有一种方法可以运行先前的转换来轻松转换特定值而不修改结构?

更新:( DevNull询问我的输出需求)输出未完全确定。我正在尝试帮助CivFanatics的一个小组制作一个关于其值来自xml文件的AI之间差异的指南。有大量的领导者和大量的价值观需要转换,他们现在每个领导者花费2个小时,最终的格式还没有决定,所以我想我们都可以通过使用像XLST。

以下是我正在进行的演示的一个粗略示例。

<xsl:template match="data"> 
  <h3>Attitude Thresholds</h3>
  <table border="1">
    <tr><td>Will open borders</td><td><xsl:value-of select="a"/></td></tr>
    <tr><td>Will trade techs</td><td><xsl:value-of select="b"/></td></tr>
  </table>
</xsl:template>

澄清A和B是OpenBordersRefuseAttitudeThreshold和TechRefuseAttitudeThreshold。如果这些是WillOpenBordersAt和WillTradeTechAt而不是xml文件中的原始值,那么该指南更具可读性,因此我需要将它们微调为最终输出的值。

还讨论了其他转化次数:

iWonderConstructRand -> Builds Wonders

0 -> 0/10
5 -> 1/10
10 -> 2/10
15 -> 3/10
20 -> 4/10
25 -> 5/10
30 -> 6/10
35 -> 7/10
40 -> 8/10
45 -> 9/10
50 -> 10/10

这样的值如C或D.它们的范围在0到50之间,为了便于阅读,应该放在0-10格式中。这些价值也很少。

还有像“GoodieBaddie”这样的转换,从0到10不等。我们希望转换为类似的内容:

0-3  -> Bad(x)
4-6  -> Neutral(x)
7-10 -> Good(x)

其中(x)是原始值。 我甚至在这里使用合适的工具还是边缘线?我认为XLST是一个不错的选择,让其他贡献者不必依赖开发人员来改变格式/布局(因为xlst更容易编辑,然后说C#或Python)。

1 个答案:

答案 0 :(得分:1)

此转化

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:attitudes>
   <a val="1">ANNOYED</a>
   <a val="2">CAUTIOUS</a>
   <a val="3">PLEASED</a>
 </my:attitudes>

 <xsl:variable name="vAttitudes" select="document('')/*/my:attitudes/*"/>

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

 <xsl:template match="*[starts-with(., 'ATTITUDE_')]/text()">
  <xsl:variable name="vVal" select=
  "$vAttitudes[. = substring-after(current(), '_')]/@val"/>

  <xsl:value-of select="concat('ATTITUDE_', $vAttitudes[@val = $vVal+1])"/>
 </xsl:template>

 <xsl:template match="*[floor(.) = .]/text()">
  <xsl:value-of select="concat(round(. div 5), '/10')"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<root>
    <data>
        <a>ATTITUDE_ANNOYED</a>
        <b>ATTITUDE_CAUTIOUS</b>
        <c>25</c>
        <d>30</d>
    </data>
</root>

会产生想要的正确结果:

<root>
   <data>
      <a>ATTITUDE_CAUTIOUS</a>
      <b>ATTITUDE_PLEASED</b>
      <c>5/10</c>
      <d>6/10</d>
   </data>
</root>