考虑以下 XML:
<paratext ID="p34"><bold>pass</bold> <bold>pass</bold></paratext>
<paratext ID="p35"><bold>pass</bold></paratext>
<paratext ID="p36">foo <bold>pass</bold> bar</paratext>
<paratext ID="p37">foo<bold> pass </bold>bar</paratext>
<paratext ID="p38"><bold>fail</bold><bold>fail</bold></paratext>
<paratext ID="p39">foo<bold>fail</bold>bar</paratext>
p34 应该通过,因为粗体标签的字母之间没有字母
p35 应该通过,因为粗体标签的外部没有字母字符
p36 应该通过,因为粗体文本和其他文本之间没有字母
p37 应该通过,因为粗体文本和其他文本
之间没有字母 p38 应该失败,因为粗体 alpha 字符之间没有 alpha 字符
p39 应该失败,因为粗体文本和“foo”或“bar”之间没有 alpha 字符
我通过 schematron 尝试这样做是这样的:
<iso:rule context="//jd:csc|//jd:bold|//jd:ital|//jd:underscore">
<iso:assert test="
string-length(preceding-sibling::text()) = 0
or
matches(substring(preceding-sibling::text(), string-length(preceding-sibling::text())), '[^a-zA-Z]')
or
matches(substring(.,1,1), '[^a-zA-Z]')
">
{WS1046} An .alpha character cannot both immediately preceed and follow <<iso:value-of select="name()"/>> tag
</iso:assert>
<iso:assert test="
string-length(following-sibling::text()) = 0
or
matches(substring(following-sibling::text(), 1,1), '[^a-zA-Z]')
or
matches(substring(., string-length(.)), '[^a-zA-Z]')
">
{WS1046} An .alpha character cannot both immediately preceed and follow </<iso:value-of select="name()"/>> tag
</iso:assert>
</iso:rule>
这样做的问题是它只查看当前上下文的父级的直接子文本节点。因此,p38 不会失败,因为没有直接的子文本节点。此外,类似的东西b<foo>bar <bold>pass</bold>
会失败,因为它只会看到“b”preceding-sibling::text()
而不会看到"foo "
.
我也尝试过::*/text()
代替::text()
,但后来我遇到了类似的问题,因为我只看到兄弟元素中的文本,没有得到直接的兄弟文本节点。我需要把这两个东西放在一起,有人知道怎么做吗?
例如,在这个 xml 中:
<paratext ID="p1">hello <foo>bar</foo> <bold>THIS</bold> <foo>bar</foo>goodbye</paratext>
当上下文规则命中<bold>THIS</bold>
并检查前面时,我希望它看到"hello bar "
,当检查以下时,我希望它看到" bargoodbye"
.