XSL для изменения проприетарного XML-документа Blumind

Я пытаюсь изменить собственный файл XML, используя XSL и MSXSL. Речь идет о программном обеспечении Blumind (blumind.org), очень красивом и полностью портативном приложении для составления карт разума (у меня нет связи с автором). Он предлагает «индикаторы прогресса», и я хотел бы, чтобы прогресс в каждом узле отражал сумму прогресса ниже. Я намерен использовать это как комбинированный инструмент моделирования и управления проектами.

Я планирую запускать пакетный файл, вызывающий MSXML.EXE каждый раз, когда я загружаю один из этих файлов, чтобы обновлять ход выполнения. Важно, чтобы структура файла оставалась неизменной, менялись только значения в различных точках /map/nodes/node/widgets/widget/@value, а затем соответствующие точки /map/nodes/node/widgets/widget/@max.

Не все узлы будут иметь индикатор выполнения, не все узлы с индикаторами выполнения будут иметь дочерние элементы с индикаторами выполнения. Таким образом, логика должна изменить индикатор выполнения только на сумму прогресса в дочерних элементах - если у детей есть индикаторы выполнения! Там, где @value для «прогресса» изменено, нам нужно сделать аналогичное изменение в значении @max, чтобы синхронизировать знаменатель с «прогрессом» (виджет будет отображать правильные пропорции, но не будет вычислять процент — он просто добавляет "%" к значению!).

Извините, если это трудно визуализировать, я бы порекомендовал загрузить портативный zip-файл версии 1.3 с http://blumind.org/download и загрузите этот файл (переименуйте 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? Сценарий идентификации выглядит полезным для сохранения файловой структуры. Однако я в замешательстве, пытаясь написать логику, чтобы изменить значения для прогресса. Инстинкт подсказывает мне, что если бы файл анализировался в обратном порядке, было бы намного проще!

Назад: 1. Для каждого нового терминала ветки - если обнаружен индикатор выполнения, сохраните промежуточную сумму для @value и @max. 2. Назначьте этот промежуточный итог любым дальнейшим индикаторам выполнения, пока две ветви не сойдутся. 3. В месте схождения добавьте два набора итогов и продолжайте.

Поскольку у каждого узла может быть более одного индикатора выполнения, было бы неплохо повторить вычисления отдельно для каждого найденного цвета индикатора выполнения — вызов мастерам XSL!

Буду очень благодарен за любую помощь.


person Gavin    schedule 14.03.2012    source источник
comment
Итак, вы хотите сгенерировать новый XML-файл с точно такой же структурой и содержимым примера, который вы опубликовали, но с @max и @value для виджетов индикатора выполнения, равными сумме виджетов дочернего индикатора выполнения с тем же цветом - верно?   -  person MiMo    schedule 14.03.2012
comment
Большое спасибо, это работает отлично. Я добавлю ссылку на эту тему на сайте Blumind. Я начинаю видеть мощь XSL. С уважением.   -  person Gavin    schedule 15.03.2012
comment
ссылка Готово.   -  person Gavin    schedule 15.03.2012


Ответы (1)


Это должно делать то, что я описываю в своем комментарии к вашему вопросу:

<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 не имеет дочерних элементов и что они могут иметь только те атрибуты, которые перечислены в вашем примере.

person MiMo    schedule 14.03.2012