как поместить шаблоны / наследование в конфигурационные файлы? - PullRequest
0 голосов
/ 21 декабря 2010

Я работаю над моделью с различными категориями объектов, каждый с различными версиями.Я хотел бы, чтобы они были доступны по умолчанию в файле конфигурации, но также позволил пользователям легко настроить значения по умолчанию.

Вот как будет выглядеть общий случай:

<containers>
  <container1>
    <object1>
      <param1>42</param1>
      <param2>3.14159</param2>
    </object1>
    <object2>
      <param3>2.71828</param3>
      <param4>auto</param4>
    </object2>
  </container1>
</containers>

Я хотел бы обработать этот следующий блок, и чтобы полученная структура объекта была идентична структуре, созданной в предыдущем блоке.

<templates>
  <object1 id="object1_1.0">
    <param1>42</param1>
    <param2>1</param2>
  </object1>
  <object2 id="object2_1.0">
    <param3>2</param3>
    <param4>auto</param4>
  </object2>
</templates>
<containers>
  <container1>
    <object1 ref="object1_1.0">
      <!--param1 "inherited" as "42"-->
      <param2>3.14159</param2>
    </object1>
    <object2 ref="object2_1.0">
      <param3>2.71828</param3>
      <!--param4 "inherited" as "auto"-->
    </object2>
  </container1>
</containers>

То есть я хотел бы иметь возможность получить то же дерево из чтенияэти два разных входных файла.Я ожидаю прочитать в XML и затем обработать полученное дерево, прежде чем смогу сгенерировать дерево объектов.

Я не смог найти никаких ссылок на это, что делается в других проектах - я недаже уверен, как его искать.Если вы сделали это, как вы подошли к этому?Иначе как ты думаешь?Или вы пробовали это и нашли это более сложным, чем оно того стоит?

Ответы [ 2 ]

1 голос
/ 29 декабря 2010

Вы можете использовать xslt, например:

<?xml version="1.0" encoding="UTF-8"?>

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

<!-- Process all containers -->
<xsl:template match="containers">
    <xsl:for-each select="child::node()">
        <!--Copy Container node  -->
        <xsl:copy>
            <xsl:for-each select="child::node()">
                <xsl:copy>
                    <!-- first copy template node -->
                    <xsl:for-each select="//node()[@id=current()/attribute::ref]/child::node()">
                        <xsl:copy>
                            <xsl:apply-templates select="@*|node()"/>
                        </xsl:copy>
                    </xsl:for-each>
                    <!--Then the object nodes -->
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:for-each>
</xsl:template>

<!-- =====================================================
 recursive copy,
 but skip templates nodes and ref attributes
-->
<xsl:template match="@ref"/>
<xsl:template match="templates"/>
<!-- Skip ref attributes -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

Это не идеально, потому что не удаляет повторяющиеся параметры, но этодолжно быть выполнимо (или использовать другой xslt для этого шага).

0 голосов
/ 23 декабря 2010

Напишите XML, который вы можете легко прочитать, и примените xpath и xslt:

  1. Используйте имена узлов, дифференцированные по атрибутам.<object2> становится <object name="2">, а <param3> становится <param name="3">.Атрибут «ref», кажется, отражает эту идею, но повторяет информацию уже в XML.Предположите это вместо этого.
  2. После выполнения # 1 используйте значения атрибутов, которые имеют значение для ваших конечных пользователей.Вместо <param2> возможно <param name="pi">.

Эти два шага открывают простые запросы xpath, такие как /templates/object, который дает итеративный результат на языке программирования, и возможность представлять ваши данные как вложенный словарь / карту / структуру.Выполните итерацию один раз, чтобы настроить шаблоны, и второй раз, чтобы переопределить параметры объекта.

Если ваши пользователи будут редактировать файлы XML напрямую, рассмотрите один шаблон или объект на файл и примените некоторые соглашения об именах и / или структуру каталогов.Это облегчит идентификацию файлов по мере роста системы.

Шаблон:

<!-- templates/1.xml -->
<template container="1" id="1">
   <param name="1">42</param>
   <param name="2">1</param>
</object>

Объект:

<!-- objects/1_1.xml -->
<object container="1" id="1">
   <!--param1 "inherited" as "42"-->
   <param name="2">3.1459</param>
</object>

Наконец, системы управления контентом часто решают проблемы, аналогичные описанным вами.Хорошее место для изучения - реализация репозитория содержимого Java Apache Jackrabbit Node Type Notation .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...