0

我想用打开/关闭标签转换处理指令,如下所示:

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

我试图实现处理指令转换,但第一个 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 的第一周。

4

2 回答 2

0

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

为了达到您的预期结果,您必须:
(1)将“开放”PI变成一个跨度;
(2) 将“包含”的文本节点放置在 span 元素内;
(3) 禁止默认模板复制相同的文本节点;(
4) 抑制“关闭”PI。

请注意,术语“开放 PI”、“包含文本”和“关闭 PI”是虚构的;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>
于 2014-07-11T00:21:46.690 回答
0

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

不确定您从哪里获得“div”,也许您应该显示更多的 XML。但是,更简单的答案是仅在 PI“开始”上触发输出并使用 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,并根据这些内容(如“粗体”或“斜体”)做出决定。

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

于 2014-07-11T02:51:30.787 回答