我正在尝试使用XSL和MSXSL修改专有XML文件。有问题的软件是Blumind(blumind.org)一个非常漂亮且完全可移植的思维导图应用程序(我与作者没有关系)。它提供“进度条”,我希望每个节点的进度反映下面的进度总和。我打算将其用作组合项目建模和管理工具。
我计划在每次加载其中一个文件时运行一个调用MSXML.EXE的批处理文件来更新进度。重要的是文件的结构保持不变,只改变各种/ map / nodes / node / widgets / widget / @值点的值,然后改变对应的/ map / nodes / node / widgets / widget / @max点。
并非所有节点都有进度条,并非所有带进度条的节点都会有进度条的子节点。所以逻辑只需要将进度条改为子进程的总和 - 如果孩子有进度条!如果“进度”的@value被更改,我们需要对@max值进行类似的更改,以使分母与“进度”保持同步(小部件将显示正确的比例,但不会计算百分比 - 它justs将“%”添加到值!)。
很抱歉,如果难以想象,我建议从http://blumind.org/download下载1.3版便携式zip文件并加载此文件(重命名test.bmd): -
对不起,我已经尝试了很多方法来识别这段代码 - 我应该怎么做?
<?xml version="1.0" encoding="utf-8"?>
<map name="test" document_type="Blumind" editor_version="1.3.21.1">
<!--Create by Blumind, you can download it free from http://www.blumind.org/download-->
<info>
<author>
</author>
<company>
</company>
<version>1.0</version>
</info>
<layout>TREE_RIGHT</layout>
<attributes>
<item name="editor_show_sidebar">True</item>
</attributes>
<style>
<back_color>White</back_color>
<fore_color>Black</fore_color>
<line_color>LightSlateGray</line_color>
<border_color>SlateGray</border_color>
<node_back_color>LightGray</node_back_color>
<node_fore_color>Black</node_fore_color>
<select_color>RoyalBlue</select_color>
<hover_color>MediumSlateBlue</hover_color>
<link_line_color>Green</link_line_color>
</style>
<nodes>
<node text="Overall Progress">
<style>
<back_color>Silver</back_color>
<fore_color>Black</fore_color>
<border_color>Black</border_color>
<padding>12</padding>
</style>
<widgets>
<widget type="PROGRESSBAR" max="1000" min="0" value="500" show_text="False"
color="Green" back_color="White" fore_color="Black" height="39" align="Bottom" hyperlink="" />
</widgets>
<nodes>
<node text="Source Code " width="200">
<widgets>
<widget type="PROGRESSBAR" max="10" min="0" value="20" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
<nodes>
<node text="Primary Module" width="100">
<widgets>
<widget type="PROGRESSBAR" max="100" min="0" value="50" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
</node>
<node text="Legacy Import" width="100">
<widgets>
<widget type="PROGRESSBAR" max="100" min="0" value="50" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
</node>
</nodes>
</node>
<node text="Unit Testing" width="200">
<widgets>
<widget type="PROGRESSBAR" max="100" min="0" value="50" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
</node>
<node text="Acceptance Testing" width="200">
<widgets>
<widget type="PROGRESSBAR" max="100" min="0" value="20" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
</node>
<node text="Usability Testing" width="200">
<widgets>
<widget type="PROGRESSBAR" max="100" min="0" value="5" show_text="False"
color="Green" back_color="White" fore_color="Black" align="Bottom" hyperlink="" />
</widgets>
</node>
</nodes>
</node>
</nodes>
</map>
我是XSL的新手并且正在挣扎,我会更好地使用AWK吗?标识脚本看起来对保留文件结构很有用。但是,我正试图编写逻辑来改变进度值。 Instinct告诉我文件是否向后解析会更容易!
向后: 1.对于每个新的分支终端 - 如果检测到进度条,则保持@value和@max的运行总计。 2.将此运行总计分配给任何进一步的进度条,直到两个分支收敛。 3.在汇合处添加两组总计并继续。
由于每个节点可以有多个进度条,因此对于找到的每个单独颜色的进度条分别重复计算会很好 - 对XSL向导的挑战!
我将非常感谢任何帮助。
答案 0 :(得分:0)
这应该是我在对你的问题的评论中所描述的:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="widget[@type='PROGRESSBAR']">
<xsl:variable name="color" select="@color"/>
<xsl:variable name="childProgressBars" select="../../nodes//widget[@type='PROGRESSBAR' and @color=$color and not(../../nodes//widget)]"/>
<xsl:variable name="value">
<xsl:choose>
<xsl:when test="$childProgressBars">
<xsl:value-of select="sum($childProgressBars/@value)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="max">
<xsl:choose>
<xsl:when test="$childProgressBars">
<xsl:value-of select="sum($childProgressBars/@max)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@max"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<widget type="PROGRESSBAR" max="{$max}" min="{@min}" value="{$value}" show_text="{@showText}"
color="{@color}" back_color="{@back_color}" fore_color="{@fore_color}" align="{@align}" hyperlink="{@hyperLink}" />
</xsl:template>
</xsl:stylesheet>
我假设widget
元素没有子元素,并且它们只能包含示例中列出的属性。