Cómo cambiar XML basado en la expresión regular coincide con texto (datos de caracteres)

StackOverflow https://stackoverflow.com/questions/1033289

  •  06-07-2019
  •  | 
  •  

Pregunta

Estoy tratando de coincidir con el contenido de texto(datos de caracteres) de un archivo XML con una serie de regexs y, a continuación, cambiar el XML basado en los partidos.Ejemplo:

 <text>
 <para>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
 </para>
 </text>

Quiero coincidir, por ejemplo, la siguiente expresión regular para el texto:

\bdolor.\b

Para cada partido, yo quiero por ejemplo rodean el partido con etiquetas o similares por lo anterior se convierte en:

<text>
<para>Lorem ipsum <bold>dolor<bold/> sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et <bold>dolore<bold/> magna aliqua.
</para>
</text>

Una complicación adicional es que el texto(datos de caracteres) quiero partido contra podría abarcar varias etiquetas.

Supongo que lo que estoy tratando de hacer es muy similar a lo que un procesador de textos de la aplicación tendría que hacer si usted hace una búsqueda que selecciona una coincidencia parte del texto y, a continuación, por ejemplo, cambiar el formato de la igualada/texto seleccionado.

Me gustaría usar Java(en realidad Clojure) para hacer esto y tengo la intención de utilizar JAXB para manipular el documento XML.

¿Cómo puedo ir haciendo arriba?

¿Fue útil?

Solución

EDITAR:

OK, ahora que entiendo que esto puede ir a través de etiquetas creo que entiendo la dificultad aquí.

El único algoritmo que puedo pensar de aquí a pie en el árbol XML de la lectura de los partes de texto de la búsqueda de su partido - que necesita para hacer esta coincidencia mismo carácter por carácter a través de múltiples nodos.La dificultad, por supuesto, es no munge el árbol en el proceso de...

Esto es lo que yo haría:

Crear un andador para caminar hasta el árbol XML.Cuando crees que has encontrado el inicio de la cadena de partido, ahorrar todo lo que el actual nodo primario.Cuando (y si) se encuentra al final de su coincidencia con la cadena de comprobar si la guarda nodo es el mismo que el final del nodo padre.Si son la misma, entonces su seguro para modificar el árbol.

Ejemplo doc:

<doc>This is a an <b>example text I made up</b> on the spot! Nutty.</doc>

Prueba 1:Partido:ejemplo de texto

El walker iba a caminar a lo largo hasta que encuentra la "e" en el ejemplo, y se ahorraría el nodo padre (<b> nodo) y seguir caminando hasta que se encontró al final de text donde se iba a comprobar para ver si todavía estaba en el mismo nodo de referencia <b> que es, así que es un partido y no se pueden etiquetar con o lo que sea.

Prueba 2:Partido:un ejemplo

El walker primer golpe a y rápidamente lo rechazan, a continuación, pulse an y guardar la <doc> nodo.La continuación de su partido a la example de texto hasta que se da cuenta de que el ejemplo del nodo primario <b> y no <doc> punto en el cual el partido se fallado y ningún nodo está instalado.

Aplicación 1:

Si sólo la coincidencia de texto directamente, entonces la simple comparador usando Java (SAXO o algo) parece un camino a seguir aquí.

Aplicación 2:

Si la coincidencia de la entrada es de regex en sí, entonces usted necesitará algo muy especial.Yo no sé de ningún motor que podría trabajar aquí seguro, lo que podría ser capaz de hacer es escribir un poco feo algo...Tal vez algún tipo de recursivas walker, que vendría abajo el árbol XML en otros más pequeños y más pequeños conjuntos de nodos, las búsquedas en el texto completo en cada nivel...

Muy rugosa (no de trabajo) código:

def search(raw, regex):
    tree = parseXml(raw)
    text = getText(tree)
    if match(text, regex):


def searchXML(tree, regex):
    text = getFlatText(tree)
    if match(text, regex): # check if this text node might match
        textNodes = getTextNodes(tree)
        for (tn : textNodes): # check if its contained in a single text node
            if match(tn, regex):
                return tn
        xmlnodes = getXMLNodes(tree)
        for (xn : xmlnodes): # check if any of the children contain the text
            match = searchXML(xn, regex)
            if match
                return match
        return tree # matches some combination of text/nodes at this level
                    # but not at a sublevel
    else:
        return None # no match in this subtree

Una vez que sabes donde está el nodo que debe contener su partido, no estoy seguro de lo que se puede hacer, porque aunque usted no sabe cómo se puede averiguar el índice dentro del texto donde es necesario partir de la regex...Tal vez alguien tiene una regex por ahí que usted puede modificar...

Otros consejos

Supongo que " el texto con el que quiero hacer coincidir abarcará varias etiquetas " significa algo como esto:

 In <i>this</i> example, I want to match "In this example".

 In <i><b>this</b></i> example, I also want to match "In this example".

 And <i>in <b>this</b></i> example, it's clear I have to ignore case too.

Esto parece un problema especialmente difícil porque la transformación de la que estás hablando puede dar como resultado un XML que no está bien formado, p. mira lo que sucede si intentas poner etiquetas alrededor de la subcadena aquí:

In this <i>example, putting tags around "in this example"</i> will break things.

<i>And in this</i> example, you have a similar problem.

Para producir una salida bien formada, probablemente necesitará que se vea así:

<bold>In this <i>example</i><bold><i>, putting tags around "in this example"</i> will break things.

<i>And <bold>in this</bold></i><bold> example</bold>, you have a similar problem.

En teoría, cada personaje que coincida podría estar en un elemento diferente:

Almost like <i><u>i</u><u>n</u> </i><u>th</u>is<i><i><u> ex</i>am</i>ple.</i>

Tiene básicamente dos problemas aquí, y ninguno es simple:

  1. Busque una secuencia de XML para una subcadena, ignorando todo lo que no sea un nodo de texto, y devuelva las posiciones de inicio y finalización de la subcadena dentro de la secuencia.

  2. Dados dos índices arbitrarios en un documento XML, cree un elemento que encierre el texto entre esos índices, cerrando (y reabriendo) cualquier elemento cuyas etiquetas abarquen los dos índices, pero no ambos.

Para mí es bastante claro que XSLT y las expresiones regulares no te ayudarán aquí. No creo que usar un DOM te ayude aquí tampoco. De hecho, no creo que haya una respuesta al segundo problema que no implique escribir un analizador.

Esto no es realmente una respuesta, lo sé.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top