使用XSL将_font处理指令转换为css

时间:2014-07-10 23:14:52

标签: xml xslt processing-instruction

我想用开/关标签转换Processing指令,如下所示:

    <para><?Pub _font Weight="bold"?>Date Re-inspected<?Pub /_font?></para>

 <div class="x-para-9-5"><span style="font-weight: bold">Date Re-inspected</span></div>

我尝试实现Processing instructions transform,但第一个PI的直接兄弟文本节点的第二个副本没有被删除(作为一个新手,我不明白为什么这个代码会删除它):

我不受欢迎的结果:

<div class="x-para-9-5"><span style="font-weight:bold;">Date Re-inspected</span>Date Re-inspected</div>

这是我的代码,稍微修改了上面引用的其他问题:

<xsl:template match="processing-instruction('Pub')">
<xsl:choose>
    <xsl:when test="starts-with(., '_font')">
      <xsl:choose>
          <xsl:when test="contains(.,'bold')">
              <span style="font-weight:bold;">
              <xsl:apply-templates select="following-sibling::node()[1][self::text()]"/>
              </span>
         </xsl:when>
    </xsl:choose>
   </xsl:when>
   <xsl:when test="starts-with(., '/_font')
      | text()[preceding-sibling::node()[1][self::processing-instruction('_font')]]">
   </xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>

任何建议都表示赞赏,这是我使用XSL的第一周。

2 个答案:

答案 0 :(得分:0)

这不是您在使用XSLT的第一周内应该做的事情。简而言之,这里的主要问题是两个处理指令是单个节点 - 它们之间的文本也是如此。

要达到预期的效果,您必须:
(1)打开&#34;打开&#34; PI进入跨度;
(2)放置&#34;包含&#34; span元素内的文本节点;
(3)禁止同一文本节点被默认模板复制;和
(4)抑制&#34;关闭&#34; PI。

请注意,条款&#34;打开PI&#34;,&#34;包含文字&#34;并且&#34;关闭PI&#34;是小说; XSLT将它们视为三个兄弟节点。

尝试以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

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

<xsl:template match="processing-instruction('Pub')[starts-with(., '_font Weight')]">
    <span style="font-weight: {substring-before(substring-after(., '&quot;'), '&quot;')}">
        <xsl:copy-of select="following-sibling::text()[1]"/>
    </span>
</xsl:template>

<!-- suppress text between PIs -->
<xsl:template match="text()[count(preceding-sibling::processing-instruction()) = count(following-sibling::processing-instruction())]"/>

<!-- suppress "closing" PIs -->
<xsl:template match="processing-instruction('Pub')[starts-with(., '/')]"/>

</xsl:stylesheet>

如果将以上内容应用于以下测试输入

<para>Opening plain text <?Pub _font Weight="bold"?>bold part<?Pub /_font?> closing plain text.</para>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<div>Opening plain text <span style="font-weight: bold">bold part</span> closing plain text.</div>

答案 1 :(得分:0)

这个问题有点不清楚。如果PI总是只标记元素(意味着您没有混合内容,并且它们只包含元素中的所有文本),那么您可以执行以下操作:

不知道你在哪里获得&#34; div&#34;来自或许你应该展示更多的XML。但是,更简单的答案是仅触发PI&#34; start&#34;并使用xsl:attribute。

抛出一个属性

鉴于此输入:

 <para><?Pub _font Weight="bold"?>Date Re-inspected<?Pub /_font?></para>

这个XSL:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
    <xsl:template match="para">
        <span>
            <xsl:apply-templates/>
        </span>
    </xsl:template>
    <xsl:template match="processing-instruction('Pub')">
        <xsl:choose>
        <xsl:when test="starts-with(., '_font')">
            <xsl:choose>
                <xsl:when test="contains(.,'bold')">
                    <xsl:attribute name="style">
                        <xsl:text>font-weight:bold;</xsl:text>
                    </xsl:attribute>
                </xsl:when>
            </xsl:choose>
        </xsl:when>
        </xsl:choose>
    </xsl:template>
    </xsl:stylesheet>

你明白了:

 <span style="font-weight:bold;">Date Re-inspected</span>

您可以对此进行扩展以处理元素中的多个PI,并对其内容做出决策(例如&#34;粗体&#34;或&#34;斜体&#34;)。

给出的另一个答案是处理内联PI的更好解决方案,这些内联PI不是父元素的直接子元素(即它们可以是内联的任何位置)。这就是为什么你应该展示更多所需的输入XML。