Как соблюдать порядок XML с `<xsl: apply-template>` с XSLT? - PullRequest
1 голос
/ 14 октября 2011

Я работаю над генерацией кода Java, и XSLT, в котором есть множество <xsl:if> или <xsl:choose>, не поддерживается.

Порядок полей важен для сообщения, и я нашел единственный способ создать другое поле - использовать регистр переключения для другого атрибута.

Это пример данных XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<message class="Message" length="28" id="0x12457836" 
                            package="org.goinfre.mail.data">
  <comment>bulk message</comment>
  <field name="state" type="short" size="2"/>
  <field name="reserve" size="2" reserved="true"/>
  <field name="reserve" size="1" reserved="true"/>
  <field name="identification" type="char">
    <array size="32" sizeName="IDENT_SIZE" encoding="UTF8" />
  </field>
  <field name="validity" type="int" size="4"/>
  <field name="voie" type="long" size="8"/>
</message>

Соответствующий XSL слишком длинный, но, например, для каждого поля я использую <xsl:choose>, потому что важен порядок буфера сообщения кодирования и декодирования. Мне нужно использовать каждое поле более одного раза.

<xsl:template match="/message">
  [...]
  <xsl:apply-templates select="field" mode="generateField"/><xsl:text>
  [...]
@Override
public byte[] toByteArray() {
    ByteBuffer buffer = ByteBuffer.allocate(LENGTH);
    super.toByteArray(buffer);
</xsl:text>
<xsl:apply-templates select="field" mode="generateBuffer"/>
    <xsl:text>
    return buffer.array();
}
</xsl:template>
<!--
*****************************************************************
** Generate a private field declaration.
**************************************************************-->
<xsl:template match="field" mode="generateField">
    <xsl:choose>
        <xsl:when test="array">
private int <xsl:value-of select="array/@sizeName"/><xsl:text> = </xsl:text><xsl:value-of select="array/@size"/>;
private <xsl:value-of select="@type"/><xsl:text>[] </xsl:text><xsl:value-of select="@name"/>
            <xsl:text> = new </xsl:text><xsl:value-of select="@type"/>
            <xsl:text>[</xsl:text><xsl:value-of select="array/@sizeName"/><xsl:text>];</xsl:text>
        </xsl:when>
        <xsl:when test="not(@reserved)">
private <xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;
        </xsl:when>
    </xsl:choose>
</xsl:template>

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

  • Это правильный способ использования XSL?
  • Есть ли у вас какие-либо советы о том, как генерировать код с помощью XSLT?

Примечание : я все еще могу изменить формат XML.

1 Ответ

2 голосов
/ 14 октября 2011

Создание более специализированных шаблонов. Переместите критерии из ваших условных операторов, которые находятся внутри шаблона, в критерии соответствия шаблонов.

Примечание: , что несколько шаблонов могут соответствовать элементу. Если они имеют одинаковый уровень специфичности в критериях соответствия, они получат одинаковый вычисленный приоритет. Возможно, вам придется указать @priority в шаблонах, чтобы «разорвать связь» и контролировать, какой из них должен срабатывать. В этом случае я добавил priority="1" в шаблон для field[array], чтобы обеспечить его соответствие вместо поля для поля [not (@reserved)] `.

Например:

<!--
*****************************************************************
** Generate a private field declaration 
    for fields that have array elements.
**************************************************************-->
<xsl:template match="field[array]" priority="1" mode="generateField">

private int <xsl:value-of select="array/@sizeName"/><xsl:text> = </xsl:text><xsl:value-of select="array/@size"/>;
private <xsl:value-of select="@type"/><xsl:text>[] </xsl:text><xsl:value-of select="@name"/>
            <xsl:text> = new </xsl:text><xsl:value-of select="@type"/>
            <xsl:text>[</xsl:text><xsl:value-of select="array/@sizeName"/><xsl:text>];</xsl:text>

</xsl:template>

<!--
*****************************************************************
** Generate a private field declaration
    for fields that do not have the attribute reserved.
**************************************************************-->
<xsl:template match="field[not(@reserved)]" mode="generateField">

private <xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;

</xsl:template>

Это также может улучшить производительность, поскольку критерии соответствия могут быть оптимизированы процессорами XSLT.

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