XSLT:处理内部XML
本文关键字:XML 内部 处理 XSLT | 更新日期: 2023-09-27 18:07:19
我正在尝试处理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>
但是我想处理它,以便在其他标签中转换内部标签。例如:
& lt; costant>text 应当成为 & lt; i> text
和
*
如何达到这个结果?
在Alexander帮助我之后,我得到了我必须调用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>
我在foreach指令之后调用xsl:apply-template:
/// <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>
技巧之一是理解函数式和声明式编程的强大功能。你现在有一个非常命令式的风格,所以让我们重写一下;
<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()。