Рассмотрят следующий 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 должны не потому, что там не являются альфа-символами между t он полужирный альфа символы
p39 должны терпят неудачу, потому что нет альфа-символы между жирным текстом и «Foo» или «бар»
Моя попытка сделать это с помощью 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"
.