Obtenga todo el contenido de texto de hermanos anterior/siguiente

Considere el siguiente 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 debería pasar porque no hay alfa entre las letras de las etiquetas en negrita
p35 debería pasar porque no hay caracteres alfa en el exterior de las etiquetas en negrita
p36 debería pasar porque no hay alfa entre el texto en negrita y otro texto
p37 debería pasar porque no hay alfa entre el texto en negrita y otro texto
p38 debería fallar porque no hay caracteres alfa entre los caracteres alfa en negrita
p39 debería fallar porque no hay caracteres alfabéticos entre el texto en negrita y "foo" o "bar"

Mi intento de hacer esto a través de schematron ha sido este:

<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 &lt;<iso:value-of select="name()"/>&gt; 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 &lt;/<iso:value-of select="name()"/>&gt; tag
 </iso:assert>
</iso:rule>

El problema con esto es que solo mira los nodos de texto secundarios directos del padre del contexto actual. Como tal, p38 no fallaría ya que no hay nodos de texto secundarios directos. Además, algo como b<foo>bar <bold>pass</bold> fallaría porque solo vería la "b" en preceding-sibling::text() y no vería el "foo ".

Yo tambien lo he intentado ::*/text() en lugar de ::text(), pero luego me encuentro con un problema similar porque solo veo el texto dentro de los elementos hermanos y no obtengo los nodos de texto hermanos directos. Necesito juntar las dos cosas, alguien sabe como?


Por ejemplo, en este xml:

<paratext ID="p1">hello <foo>bar</foo> <bold>THIS</bold> <foo>bar</foo>goodbye</paratext>

Cuando la regla de contexto golpea <bold>THIS</bold> y está comprobando lo anterior, me gustaría que lo viera "hello bar " y al revisar lo siguiente me gustaría que viera " bargoodbye".

preguntado el 22 de noviembre de 13 a las 15:11

1 Respuestas

Bueno, con XPath 2.0 (que pareces usar mientras usas matches) puedes usar:

string-join(preceding-sibling::node(), '') 

para obtener "hello bar "y:

string-join(following-sibling::node(), '') 

para obtener " bargoodbye".

Las líneas anteriores asumen que solo tiene elementos y nodos de texto como hermanos. Si puede haber comentarios y/o instrucciones de procesamiento y desea pasar por alto su contenido para estas reglas, puede utilizar:

string-join(preceding-sibling::* | preceding-sibling::text(), '')

respondido 22 nov., 13:18

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.