Je veux extraire environ 20 types d'éléments de certains documents SVG pour former un nouveau SVG.
Trois méthodes viennent à l'esprit: p> Si XSLT est le bon outil pour le travail, quel XSL: la feuille de style ai-je besoin?
Sinon, quelle approche utiliseriez-vous? P> Exemple d'entrée: p> exemple de sortie. Affiche exactement la même image: P> rect code>,
cercle code>,
polygone code>,
texte code>,
polyline code>, essentiellement un ensemble de visuel les pièces sont dans la liste blanche.
JavaScript, commentaires, animations et liens externes doivent aller.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512">
<defs>
<circle id="my_circle" cx="100" cy="50" r="40" fill="red"/>
</defs>
<g id="layer1">
<use xlink:href="#my_circle" x="20" y="20"/>
<use xlink:href="#my_circle" x="100" y="50"/>
</g>
<text>
<tspan>It was the best of times</tspan>
<tspan dx="-140" dy="15">It was the worst of times.</tspan>
</text>
</svg>
4 Réponses :
SVGFIG est un bon outil pour ce travail. Vous pouvez charger des fichiers SVG et choisir des pièces que vous aimez créer un nouveau document. Ou vous pouvez simplement supprimer des pièces que vous ne em> pas et ne sauvegardez pas. P>
La solution de Dimitire Novatchev est plus "propre" et élégante, mais si vous avez besoin d'une solution "Whitelist" (car vous ne pouvez pas prédire ce que les utilisateurs de contenu peuvent saisir que vous auriez besoin de "liste noire"), alors vous auriez besoin de complètement chagriner le "Whitelist".
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:svg="http://www.w3.org/2000/svg"> <xsl:output indent="yes" /> <!--The "whitelist" template that will copy matched nodes forward and apply-templates for any attributes or child nodes --> <xsl:template match="svg:svg | svg:defs | svg:defs/text() | svg:g | svg:g/text() | svg:a | svg:a/text() | svg:use | svg:use/text() | svg:rect | svg:rect/text() | svg:circle | svg:circle/text() | svg:ellipse | svg:ellipse/text() | svg:line | svg:line/text() | svg:polyline | svg:polyline/text() | svg:polygon | svg:polygon/text() | svg:path | svg:path/text() | svg:text | svg:text/text() | svg:tspan | svg:tspan/text() | svg:tref | svg:tref/text() | svg:textpath | svg:textpath/text() | svg:linearGradient | svg:linearGradient/text() | svg:radialGradient | svg:radialGradient/text() | svg:clippath | svg:clippath/text() | svg:text | svg:text/text()"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:apply-templates select="node()" /> </xsl:copy> </xsl:template> <!--The "blacklist" template, which does nothing except apply templates for the matched node's attributes and child nodes --> <xsl:template match="@* | node()"> <xsl:apply-templates select="@* | node()" /> </xsl:template> </xsl:stylesheet>
Il correspond aux attributs attachés à tout élément lié à l'espace de noms SVG.
Je pensais avoir compris cela, mais quand j'ai enlevé "SVG: A |" Dans la liste, je reçois une erreur. "Les nœuds d'attributs doivent être ajoutés avant tout nœud d'enfants à un élément." J'ai utilisé XSLTPROC pour faire le traitement réel.
Aussi, je suppose que cela a besoin d'un texte () quelque part, puisqu'il élimine tous les nœuds de texte.
J'ai frappé les livres XSL. La partie liste noire mange tous les nœuds de texte, mais sans elle, tout le texte est automatiquement copié sur le nouveau document.
Copier les attributs d'un élément qui n'est pas lui-même copié me semble discutable. Ils se retrouveront soit sur le "mauvais" élément, ou ils provoqueront une défaillance, car les nœuds de texte ont déjà été écrits à l'élément parent.
@Samg - J'avais négligé d'inclure SVG: éléments de texte et svg: * / texte (). J'ai également ajouté un autre modèle "liste noire" qui mange complètement ces éléments non-SVG (qui sont dans l'espace de noms SVG, car un préfixe d'espace de noms n'a pas été utilisé pour l'élément de document SVG) et ne traite pas le nœud @ * ou enfant (), qui causait la feuille de style d'émettre leur attribut au mauvais endroit.
Les changements que j'ai dû faire apporter plus en ligne avec la solution de @dimitre Novatchev, mais il supprime également certains des autres attributs que vous voulez probablement. Sa solution est la plus "propre", car vous n'avez vraiment que de gérer la "liste noire" et tout le reste fonctionne simplement. J'accepterais sa réponse et aller avec sa feuille de style comme base de votre travail.
@Samg - J'ai fait une autre mise à jour qui reste avec l'approche "Whitelist" et semble fonctionner. Malheureusement, c'est un peu verbeux, mais je pense que produira la sortie souhaitée et gérera des éléments aléatoires supplémentaires que vous voudriez redact.
@Mads Hansen - Beaucoup de ces éléments ne sont pas autorisés à contenir des nœuds de texte de toute façon; toutes les formes de base pour un début. Je suis convaincu que si je passe quelques heures avec les spécifications SVG, votre solution est une fondation sonore.
@Mads Hansen: une solution "Liste blanche" peut également conserver la règle d'identité, il suffit d'utiliser non () code> comme dans
Cela n'a pas fonctionné pour moi (il a produit un document vide). J'ai découvert que c'est parce que mon SVG n'avait pas la déclaration d'espace de noms (xmlns = " w3.org / 2000 / SVG "). Supprimer tous les qualificatifs d'espace de noms" SVG: "sur l'attribut de match travaillée.
Est-ce que je comprends bien que le @ * génère tous les attributs? Il devrait également y avoir une blanchisseuse d'attributs, sinon des trucs comme
Oui, '@ *' correspond à n'importe quel attribut et copierait tout. Vous pouvez filtrer ceux-ci si vous choisissez.
@ HH321 Ouais aussi les XSS suivants ne sont pas filtrés: Xml version = "1.0" autonome = "non"?>
Alternative à la réponse XSLT acceptée, vous pouvez utiliser ruby et
Lorsqu'il est appliqué sur le document XML fourni fort>: p> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512">
<defs id="defs4">
<circle id="my_circle" cx="100" cy="50" r="40" fill="red"/>
</defs>
<g id="layer1">
<use xlink:href="#my_circle" x="20" y="20"/>
<use xlink:href="#my_circle" x="100" y="50"/>
</g>
<text>
<tspan>It was the best of times</tspan>
<tspan dx="-140" dy="15">It was the worst of times.</tspan>
</text>
</svg>
Votre résultat contient qui aurait dû être filtré. Cela prouve la futilité de la liste noire. Bonnes explications anglaises en anglais cependant.
@Samg: Non La solution est i> Sound, je n'avais tout simplement pas vu le a code>. Corrigé maintenant - avez un look, et nous avons maintenant un exemple de traitement d'un élément classé.
Je ne discuterai pas parce que je suis plus intéressant dans l'apprentissage de XSL. Bien que considérez la politique HTML de ce site même. "Nous n'autorisons pas toutes les étiquettes HTML, car ce serait un paradis de XSS" SVG AR Normalement de tels documents publics, mais celui-ci se trouve juste. Donc, le modèle de menace est le même, et cela n'a rien à voir avec le pessimisme.
@Samg: En laissant de côté les discussions philosophiques, cette solution résout non seulement complètement votre problème, mais une méthodologie solide pour construire de telles applications plus propres - pourquoi ne pas envisager d'accepter cette réponse?
@Dimitre Dans la plupart des cas, je pense que votre approche est la plus propre et efficace. Je pense que la question est qu'il peut ne pas savoir à l'avance sur ce que les nœuds qu'il veut redact, car il s'agit de contenu généré par l'utilisateur. Il sait seulement quel contenu il veut garder ("Whitelist").
@ Mads-Hansen: Je suis d'accord avec votre commentaire que l'OP ne sait pas exactement tous les types de nœuds qu'il veut entrer / out. C'est pourquoi j'ai inclus point 4. de l'explication. La liste noire et la liste grise augmenteront à temps, reflétant la compréhension croissante sur ce sujet. Celles-ci, ainsi que la liste blanche couvrent complètement tous les nœuds. Il n'est pas nécessaire de spécifier toutes les trois listes - l'une d'entre elles peut être traitée avec l'action par défaut et cela nous donne une commodité.
XSLT est probablement le bon outil pour le travail. Si vous pouvez fournir un bref échantillon et décrire ce que vous voulez redactiver ou conserver, vous obtiendrez probablement une réponse avec un XSLT pour vous aider à démarrer.
Bonne question, +1. Consultez ma réponse pour une solution complète qui produit exactement la production recherchée et pour une explication approfondie. :)
Contexte supplémentaire: Si le SVG était comme une page de forum, vous ne permettriez naturellement que des personnes un petit sous-ensemble de HTML, sinon toutes sortes de scripts et de vandalisme obtiendraient cependant. Ceci est un document SVG partagé, qui est conceptuellement comme un forum Web.