2011-09-03 133 views
0

我正在尝试处理XML内部文本。我有以下XSLT片段:XSLT:处理内部XML

<?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> 

,但我想处理它,才能在其它标签转换内部变量。例如:

<costant>文本< /恒>将成为<我>文本< /我>

* <参数> GL_PARAM < /参数> *将成为< paramref cref =“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:

/// <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> 
+0

实际的问题是,似乎不可能控制空间标准化(我需要一行或多行以///开头)。 – Luca

回答

2

的伎俩之一,就是:申请模板只是的foreach指令后理解函数式和声明式编程的力量。现在你已经有了一种非常强制性的风格,所以让我们稍微改写一下;

<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到G1.PARAM不是拼写错误,你需要在顶部做一些额外的文本转换,但是如果你知道公式(没说:),那么它就不那么困难了。 ,使用诸如before-substring(),after-substring()和translate()之类的东西。

+0

这将是伟大的,但它不适用于我(问题更新)。我可以调用xsl:call-template(如果我是对的),但它会更加紧迫,不是吗? – Luca

+0

此外,我认为template必须匹配* para/parameter *和* para/constant *和*/refsect1 [@ id ='errors']/para *(not * param *)。这样对吗? – Luca

+0

没有。我看不到任何模板匹配,我看不出为什么! – Luca