XSLT: обработка внутреннего XML - PullRequest
       0

XSLT: обработка внутреннего XML

0 голосов
/ 03 сентября 2011

Я пытаюсь обработать внутренний текст XML. У меня есть следующий фрагмент XSLT:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="refsect1[@id='errors']/param">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="param/constant">
        <i><xsl:apply-templates/></i>
    </xsl:template>

    <xsl:template match="param/parameter">
        <paramref cref="{.}"/>
    </xsl:template>

    <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

    <xsl:template name="summary" match="refentry">
/// <summary>
/// <xsl:value-of select="concat(translate(
                    substring(refnamediv/refpurpose, 1, 1), $lowercase, $uppercase),
                    substring(refnamediv/refpurpose, 2, string-length(refnamediv/refpurpose) - 1))"/>
/// </summary>
        <xsl:for-each select="refsect1/variablelist/varlistentry">
            <xsl:choose>
                <xsl:when test="../../@id = 'parameters'">
/// <param name="{term/parameter}">
        <xsl:for-each select="listitem/para">
/// <xsl:value-of select="normalize-space(.)"/>
        </xsl:for-each>
/// </param>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
/// <remarks>
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError"/>):
        <xsl:for-each select="refsect1[@id='errors']/para">
/// <xsl:value-of select="normalize-space(.)"/>
        </xsl:for-each>
/// </para>
/// </remarks>
        <xsl:for-each select="refsect1[@id = 'seealso']/para/citerefentry">
/// <seealso cref="Gl.{substring(refentrytitle, 3)}"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Этот XSLT должен применяться к документу XML; вот фрагмент:

<refsect1 id="errors"><title>Errors</title>
    <para>
        <constant>GL_INVALID_OPERATION</constant> is generated if <parameter>pipeline</parameter> is not
        a name previously returned from a call to <citerefentry><refentrytitle>glGenProgramPipelines</refentrytitle></citerefentry>
        or if such a name has been deleted by a call to
        <citerefentry><refentrytitle>glDeleteProgramPipelines</refentrytitle></citerefentry>.
    </para>
    <para>
        <constant>GL_INVALID_OPERATION</constant> is generated if <parameter>program</parameter> refers
        to a program object that has not been successfully linked.
    </para>
</refsect1>

Мой текущий вывод - обычный текст:

/// <remarks>
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError" />):
/// GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call to glGenProgramPipelines or if such a name has been deleted by a call to glDeleteProgramPipelines.
/// GL_INVALID_OPERATION is generated if program refers to a program object that has not been successfully linked.
/// </para>
/// </remarks>

но я бы хотел обработать его, чтобы преобразовать внутренние теги в другие теги. Например:

текст должен стать текст

и

* GL_PARAM * должно стать


Как этого добиться?


После того, как Александр помог мне, я получил вызов xsl: apply-template. Это начало работать, но я не могу контролировать нормализацию пространства:

/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError" />):
    <i>GL_INVALID_OPERATION</i> is generated if <paramref cref="pipeline" /> is not
        a name previously returned from a call to glGenProgramPipelines
        or if such a name has been deleted by a call to
        glDeleteProgramPipelines.
    <i>GL_INVALID_OPERATION</i> is generated if <paramref cref="program" /> refers
        to a program object that has not been successfully linked.

/// </para>

Я вызываю xsl: apply-template сразу после инструкции foreach :

/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError"/>):
    <xsl:for-each select="refsect1[@id='errors']/para">
        <xsl:apply-templates/>
    </xsl:for-each>
/// </para>

1 Ответ

2 голосов
/ 03 сентября 2011

Часть хитрости заключается в понимании силы функционального и декларативного программирования.У вас сейчас очень непростой стиль, поэтому давайте его немного переписаем:

<xsl:template match="refsect1[@id='errors']/param">
   <xsl:apply-templates />
</xsl:template>

<xsl:template match="param/constant">
   <i><xsl:apply-templates /></i>
</xsl:template>

<xsl:template match="param/parameter">
   <paramref cref="{.}" />
</xsl:template>

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

Наконец, если ваши GL_PARAM в Gl.PARAM не были опечаткой, вам нужно выполнить дополнительное преобразование текста сверху, но это не так сложно, если вы знаете формулу (вы не сказали:), используя что-то вроде before-substring (), after-substring () и translate ().

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