我想用这样的打开/关闭标签来转换处理指令:
<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。
这不是您在使用XSLT的第一个星期应该做的事情。简而言之,这里的主要问题是两个处理指令是单独的节点——它们之间的文本也是。
要达到预期的结果,你必须:
(1)将"开口"PI变成跨度;
(2)在span元素中放置" contains "文本节点;
(3)抑制同一文本节点被默认模板复制;和
(4)抑制"闭合"PI
请注意,术语"开始PI","包含文本"one_answers"结束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(., '"'), '"')}">
<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>
这个问题有点不清楚。如果pi总是只标记元素(这意味着您没有混合内容,并且它们只包围元素中的所有文本),那么您可以执行以下操作:
不确定您从哪里获得"div",也许您应该显示更多的XML。然而,更简单的答案是只在PI "start"时触发输出,并使用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的内容做出决定(如"粗体"或"斜体")。
给出的另一个答案是一个更好的解决方案来处理内联pi不是父元素的直接子元素(即它们可以在任何地方内联)。这就是为什么您应该显示更多所需的输入XML。