次の 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 は失敗する必要が
あります 太字テキストと「foo」または「bar」の間にアルファ文字がないため、p39 は失敗する必要があります
スキーマトロンを介してこれを行う私の試みは次のとおりです。
<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"
。