我有以下XML。我想使用XSL-FO将其转换为在<escape V=".br"/>
处添加换行符,并在<escape V="H"/>
和<escape V="N"/>
之间加粗文本。有什么建议?即使是XML-&gt; html示例也足够了。
<OBX.5>
Tan<escape V=".br"/>MB BS FRACS PhD<escape
V=".br"/>Hospital & Specialist Centre<escape
V=".br"/>Address:<escape
V=".br"/>XX XX Street<escape
V=".br"/>XXX<escape
V=".br"/>HUTT 5011<escape
V=".br"/>Date of Birth:<escape
V=".br"/>15.03.1987<escape
V=".br"/>Telephone:<escape
V=".br"/>(h) 9888 26846<escape
V=".br"/>(m) 0221 632 4590<escape
V=".br"/>HI Number:<escape
V=".br"/>JAP5065<escape V=".br"/>
<escape V=".br"/>
After the 5 dots is a Bolded Line.....<escape
V="H"/> TEST Escape Characters<escape V="N"/>TEST more
<escape V=".br"/>
</OBX.5>
答案 0 :(得分:1)
这样可行,但显式不表示嵌套格式(即粗体+斜体):
<xsl:template match="OBX.5">
<fo:block linefeed-treatment="preserve">
<xsl:apply-templates select="node()[
count(preceding-sibling::escape[@V = 'H'])
- count(preceding-sibling::escape[@V = 'N'])
= 0
]" />
</fo:block>
</xsl:template>
<!-- add a line break where there is <escape V=".br"/> -->
<xsl:template match="escape[@V = '.br']">
<xsl:text>
</xsl:text>
</xsl:template>
<!-- bold the text between <escape V="H"/> and <escape V="N"/> -->
<xsl:template match="escape[@V = 'H']">
<fo:inline font-weight="bold">
<xsl:apply-templates select="
following-sibling::escape[@V = 'N'][1]/preceding-sibling::node()[
generate-id(preceding-sibling::escape[@V = 'H'][1]) = generate-id(current())
]
" />
</fo:inline>
</xsl:template>
<!-- all other escapes are ignored -->
<xsl:template match="escape" />
<!-- trim all text nodes before output (optional, remove if unnecessary) -->
<xsl:template match="text()">
<xsl:value-of select="normalize-space()" />
</xsl:template>
样品的输出:
<block xmlns="http://www.w3.org/1999/XSL/Format" linefeed-treatment="preserve">Tan
MB BS FRACS PhD
Hospital & Specialist Centre
Address:
XX XX Street
XXX
HUTT 5011
Date of Birth:
15.03.1987
Telephone:
(h) 9888 26846
(m) 0221 632 4590
HI Number:
JAP5065
After the 5 dots is a Bolded Line.....<inline font-weight="bold">TEST Escape Characters</inline>TEST more
</block>
请注意,只有escape[@V = '.br']
实际上会创建一个换行符,所以&#34;在5个点之后是一个粗线......&#34; 不能为真你的意见。
我使用的XPath表达式需要一些解释,所以这里是。
想象一下<OBX.5>
的孩子作为这个列表:
# Node H N H-N
-------------------------------------------------------
1 Tan 0 0 0
2 <escape V=".br"/> 0 0 0
3 MB BS FRACS PhD 0 0 0
... and so on ... . . .
29 <escape V=".br"/> 0 0 0
30 After the 5 dots is a Bolded Line..... 0 0 0
31 <escape V="H"/> 0 0 0
32 TEST Escape Characters 1 0 1
33 <escape V="N"/> 1 0 1
34 TEST more 1 1 0
35 <escape V=".br"/> 1 1 0
,其中
H
是count(preceding-sibling::escape[@V = 'H'])
N
是count(preceding-sibling::escape[@V = 'N'])
H-N
显然是两者的区别。所以用
<xsl:apply-templates select="node()[
count(preceding-sibling::escape[@V = 'H'])
- count(preceding-sibling::escape[@V = 'N'])
= 0
]" />
我们处理 #32
和#33
以外的所有节点。
模板#3对#31
进行特殊处理,渲染一个包含以下内容的粗体容器:
<xsl:apply-templates select="
following-sibling::escape[@V = 'N'][1]/preceding-sibling::node()[
generate-id(preceding-sibling::escape[@V = 'H'][1]) = generate-id(current())
]
" />
XPath转换为
escape[@V = 'N']
preceding-sibling
)并选择escape[@V = 'H']
的ID与当前escape[@V = 'H']
的ID相同。此条件仅适用于您示例中的#32
和#33
,实际上它会以一种方式切片节点列表,以防止将更多文本呈现为粗体而非所需。
节点#33
被模板#4丢弃,我们只需将它用于计数目的。