Puis-je utiliser un texte en clair algorithme de comparaison pour le suivi XML changements?

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

  •  19-09-2019
  •  | 
  •  

Question

Je travaille dans Flex/AS3 (pour la simplicité) un éditeur XML.J'ai besoin de fournir annuler/rétablir la fonctionnalité.

Bien sûr, la seule solution est de stocker l'intégralité du texte source à chaque édition.Toutefois, pour conserver la mémoire, je tiens à stocker les différences au lieu de cela (ces différences seront également utilisés pour transmettre les mises à jour du serveur pour l'enregistrement automatique).


Ma question est, puis-je utiliser un texte en clair algorithme de comparaison pour le suivi de ces XML changements?

Mes recherches sur internet indique que je ne peut pas le faire.Cependant, je suis évidemment manque quelque chose.En clair diff fournit une fonctionnalité qui est censément:

diff(text, text') -> diffs
patch(text, diffs) -> text'

XML est simplement du texte, alors pourquoi ne puis-je pas simplement utiliser la commande diff() et le patch() pour transformer le texte de manière fiable?

Par exemple:Disons que je suis un poète.Quand j'écris de la poésie, j'ai utiliser beaucoup de funky, de la ponctuation...Vous savez, comme <, / et >.(Vous pouvez voir où je veux en venir...) Si je suis en train d'écrire ma poésie dans une application qui utilise les différences de fournir annuler/rétablir la fonctionnalité, ma poésie devenir illisible lorsque je annuler/refaire mes modifications?C'est juste le texte!Pourquoi a-t-il une différence pour l'algorithme?

J'ai bien évidemment de ne pas obtenir quelque chose ici...Merci pour l'explication!:)

Mise à JOUR:

Quelques discussions que j'ai rencontrés s'agissant de comparaison XML avec un texte en clair algorithme:


Aussi, je comprends qu'un modèle de Commande est susceptible d'être un meilleur moyen de mettre en œuvre Undo/Redo.J'ai simplifié mon cas d'utilisation pour des raisons de simplicité, et je ne pense toujours que XML de comparaison est la meilleure approche.

Était-ce utile?

La solution

Je suis l'auteur du texte brut diff/match/patch de la bibliothèque de la part de Google.

La question clé est de savoir si vos patchs sont exactes.Dans un monde idéal:

  diff(old_text, new_text) -> edits
  patch(edits, old_text) -> new_text

Notez que le texte de base (old_text) est le même dans les deux opérations.Dans ce cas idéal, alors qu'un simple texte brut diff et patch fonctionne parfaitement, quel que soit le type de contenu.Si ce cas s'applique à vous, alors vous êtes fait.

Le problème réside dans la floue correctifs.Voici l'exemple correspondant:

  diff(old_text, new_text) -> edits
  patch(edits, old_forked_text) -> new_forked_text

Notez que le texte de base n'est pas la même dans les deux opérations.Ils devraient être similaires, mais l'opération de patch a maintenant utiliser "jugement" à propos de ce qu'il devrait faire.Certaines taches peuvent s'adapter parfaitement comme spécifié dans l'édition, d'autres peuvent avoir besoin d'être modifié pour la position, d'autres peuvent avoir besoin d'être modifié d'une altération de contexte, d'autres peuvent ne pas convenir à tous et doit être abandonnée.Si votre patch algorithme n'est pas au courant de la structure du XML lors de la prise de ses décisions, vous peut très bien se retrouver avec malfromed XML.Voici un échantillon:

  old_text = Jabberwock<SPAN>Hello<SPAN>World</SPAN></SPAN>
  new_text = Jabberwock<DIV>Hello<SPAN>World</SPAN></DIV>
  diff(old_text, new_text) -> edits
  edits = ["SPAN" -> "DIV" @ character 11,
           "SPAN" -> "DIV" @ character 41]
  old_forked_text = <SPAN>Hello<SPAN>World</SPAN></SPAN>
  patch(edits, old_forked_text) -> new_forked_text
  new_forked_text = <SPAN>Hello<DIV>World</SPAN></DIV>

Regardons-le soigneusement.L'original diff retourné deux modifications, changement de la limite extérieure de la DURÉE d'un DIV.Changement Simple.Malheureusement, le texte de cette édition est appliqué à a changé à partir de l'original.Le mot "Jabberwock" a été supprimé.Maintenant, la première SPAN>DIV changement correspond à la deuxième balise SPAN, pas la première.Depuis le patch de l'algorithme n'est pas au courant des règles de XML, il en résulte illégalement balises imbriquées.

Il y a quelques hacks qui vous permettent de vous garantir XML valide lors de l'utilisation d'un texte brut patch, mais elles résultent en une perte de souplesse (la question d'origine a déjà un lien vers la page wiki que j'ai écrit à ce sujet).La solution ultime pour patcher XML est bien sûr l'utilisation de XML-connaissance diff et patch de l'algorithme.Ces sont nettement plus compliqué et plus cher, mais ils existent.Google le nom de Tancrède Lindholm et Sebastian Rönnau pour l'excellent travail qu'ils ont fait dans le champ XML (en particulier en ce qui concerne DocEng).

Laissez-moi savoir si il y a autre chose que je peux ajouter.

-- Neil Fraser

Autres conseils

J'utilise Au-Delà De Comparer tout le temps à comparer des documents XML.Il comprend XML, à un certain degré.

Vous pouvez avoir besoin pour pré-traiter les deux documents dans l'ordre pour le texte de comparaison à faire le meilleur travail possible.Par exemple, dans certains documents XML, de l'ordre de quelques éléments ne peut pas d'importance.Il sera certainement question de votre outil de comparaison!Vous pouvez avoir besoin de pré-traiter les données XML à l'aide d'une Transformation XML qui trie ces éléments dans un ordre commun dans les deux fichiers, avant de comparer les deux fichiers triés.

Vous souhaitez utiliser la même indentation pour les deux documents.Je trouve qu'il est utile de commencer chaque élément sur une nouvelle ligne, et d'utiliser la même quantité d'indentation, avec des espaces, pour chaque niveau.Si votre document est très profonde, vous pouvez utiliser seulement un ou deux espaces par niveau, de sorte que la comparaison s'adapte à l'écran.Vous pouvez même utiliser un attribut par ligne (et à trier les attributs dans un ordre commun).

Si vous êtes le seul "propriétaire" des données entre votre undo/redo points, alors bien sûr vous pouvez utiliser en clair diff pour eux.Comme vous le soulignez, il s'élève à une série de transformations.

Selon les opérations à vous fournir, cependant, en clair diff peuvent ne pas être à distance de près optimale pour l'enregistrement de la commande undo/redo, et vous pourriez avoir à se spécialiser certains cas.Imaginez simplement de l'enregistrement d'un ReplaceAll de commande qui peut être seulement quelques octets en plus de la recherche et de la chaîne de remplacement.Que pourrait générer massive en clair diff.

Dans le contexte plus large, si vous le permettez externe de l'édition de ces documents, et vous êtes en train de penser plus sur la façon de stocker les deltas sur le serveur, vous êtes imitant git ou d'autres systèmes de contrôle de version.Vous avez à utiliser un certain type d'algorithme de comparaison, car il suffit de l'enregistrement de vos commandes est évidemment pas la seule source de transformation.À ce stade, vous commencez à mélanger undo/redo avec le contrôle de version et vous souhaitez peut-être réfléchir à la confusion de ces concepts pour vos utilisateurs.

Je voudrais garder le undo/redo qu'à l'intérieur d'une session d'édition et de l'interdiction de modification externe alors que le fichier est ouvert.Qui vous permet d'optimiser votre commande d'enregistrement pour les grandes affaires comme je l'ai dit ci-dessus.

Au-delà, soit utiliser les classiques de contrôle de version (il est recommandé de mettre git) ou de mettre en œuvre votre propre façon de composer avec les fichiers modifiés en dehors de votre éditeur.

Je pense que vous pouvez utiliser le texte de diff pour xml surtout dans ton cas où l'être humain va écrire le code xml ligne par ligne.Je ne sais pas quelles sont les informations que vous avez obtenu en disant: vous ne pouvez pas le faire mais je suppose que la déclaration était fondée sur le fait que les caractères d'espacement (espace, tabulation, saut de ligne ...) sont un peu différents qu'ils sont dans un fichier de texte brut, ce qui pourrait entraîner deux fichiers texte sont identiques à partir d'un XML point de vue.Mais encore une fois, pour un éditeur de ciblage de l'être humain, je ne vois pas pourquoi vous ne pouvez pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top