Editar elementos SVG con selectores CSS en Python

Respuesta rápida: Para editar elementos SVG con selectores CSS en Python, cargue el archivo con SVGDocument, encuentre un destino editable con Element.query_selector() o varios nodos con Element.query_selector_all(), actualice atributos en un único elemento coincidente o contenido a nivel de nodo como text_content en varias coincidencias, y guarde el SVG.

1from aspose.svg import SVGDocument
2
3with SVGDocument("document.svg") as document:
4    element = document.root_element.query_selector("#target")
5    if element is not None:
6        element.set_attribute("fill", "#2e86de")
7    document.save("edited.svg")

Los selectores CSS son útiles cuando un archivo SVG tiene IDs, clases, atributos o grupos anidados con significado. La idea es simple: escriba un selector que apunte al elemento SVG que desea editar, actualice ese elemento y guarde el documento.

En este artículo aprenderá a:

Este artículo se centra en flujos de edición basados en selectores. Para inspección más amplia del documento, recorrido del árbol y ejemplos XPath, consulte Navegar SVG en Python.

SVG de ejemplo usado en los ejemplos

Este artículo usa el archivo de ejemplo css-selectors-edit.svg. Puede guardarlo como data/css-selectors-edit.svg antes de ejecutar los ejemplos. El SVG de ejemplo contiene tres grupos pequeños editables: #badge, #status-card y #chart. Los ejemplos siguientes usan estos grupos para mostrar cómo los selectores apuntan a partes SVG reales antes de que el código las cambie.

Cómo editar elementos SVG con selectores CSS en Python

Use este flujo cuando un archivo SVG tenga IDs, clases, atributos o grupos anidados estables:

  1. Cargue el archivo SVG con SVGDocument.
  2. Elija el selector más estrecho que identifique el objetivo, como #id, .class, tag[attribute] o un selector restringido dentro de un grupo.
  3. Use query_selector() para un elemento editable cuando necesite set_attribute().
  4. Use query_selector_all() solo para cambios seguros a nivel de nodo en muchas coincidencias, como text_content.
  5. Guarde el SVG editado y verifique que el selector no afectó elementos no relacionados.

Editar un elemento SVG por ID

Un selector ID es la opción más simple y segura cuando el elemento de destino es único. El ejemplo siguiente encuentra el círculo con id="badge-bg", cambia fill, stroke y stroke-width, y guarda el SVG editado como css-selector-edit-by-id.svg. Use este patrón para plantillas SVG donde los objetos importantes tienen IDs estables.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "css-selectors-edit.svg")
 7output_path = os.path.join(output_folder, "css-selector-edit-by-id.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    badge_background = document.root_element.query_selector("#badge-bg")
12
13    if badge_background is not None:
14        badge_background.set_attribute("fill", "#2e86de")
15        badge_background.set_attribute("stroke", "#0d47a1")
16        badge_background.set_attribute("stroke-width", "5")
17
18    document.save(output_path)

La imagen siguiente compara el SVG de origen (a) con css-selector-edit-by-id.svg (b). Solo cambia el color y el contorno del círculo seleccionado por #badge-bg; la tarjeta de estado, el gráfico y las etiquetas permanecen intactos.

SVG original y resultado editado después de cambiar el círculo badge por ID

Editar varios nodos de texto SVG por clase

Use query_selector_all() cuando el mismo cambio a nivel de nodo deba aplicarse a cada coincidencia. El SVG de ejemplo usa class="label" en todas las etiquetas de texto. El ejemplo siguiente encuentra todas las etiquetas y actualiza su contenido de texto.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "css-selectors-edit.svg")
 7output_path = os.path.join(output_folder, "css-selector-edit-labels.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    labels = document.root_element.query_selector_all(".label")
12
13    for label in labels:
14        label.text_content = label.text_content.upper()
15
16    document.save(output_path)

La salida cambia el texto de cada nodo de texto SVG con clase label. Este es el ejemplo principal para varios nodos en el artículo: usa query_selector_all() para el flujo con selectores y evita llamar Element.set_attribute() en elementos NodeList.

La imagen siguiente compara el SVG de origen (a) con el resultado guardado como css-selector-edit-labels.svg (b). Todo el texto de las etiquetas pasa a mayúsculas, mientras las formas, fill, stroke y barras del gráfico permanecen iguales. Esto mantiene el foco visual en la edición de texto basada en clases.

SVG original y resultado editado después de cambiar nodos de texto SVG por clase

Usar selectores de atributos restringidos

Los selectores de atributos restringidos son útiles cuando un selector amplio coincidiría con demasiados elementos. El ejemplo siguiente edita dos destinos distintos en un flujo: el punto de estado seleccionado por #status-card circle[fill] y la barra alta del gráfico seleccionada por #chart .bar[data-level='high'].

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "css-selectors-edit.svg")
 7output_path = os.path.join(output_folder, "css-selector-edit-scoped-attributes.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    warning_dot = document.root_element.query_selector("#status-card circle[fill]")
12    high_bar = document.root_element.query_selector("#chart .bar[data-level='high']")
13
14    if warning_dot is not None:
15        warning_dot.set_attribute("fill", "#d32f2f")
16        warning_dot.set_attribute("stroke", "#8b0000")
17        warning_dot.set_attribute("stroke-width", "4")
18
19    if high_bar is not None:
20        high_bar.set_attribute("fill", "#455a64")
21        high_bar.set_attribute("opacity", "1")
22
23    document.save(output_path)

El primer selector encuentra un círculo solo dentro de #status-card y solo si ese círculo tiene un atributo fill. El segundo selector encuentra la barra del gráfico cuyo valor data-level es high. La salida debe mostrar un punto de estado rojo y una barra alta oscura.

La imagen siguiente compara el SVG de origen (a) con css-selector-edit-scoped-attributes.svg (b). Los selectores restringidos actualizan dos destinos separados sin cambiar el badge ni las barras inferiores del gráfico. Esta es la principal ventaja de combinar grupo, clase, etiqueta y condiciones de atributo.

SVG original y resultado editado después de cambiar el punto de estado y la barra alta del gráfico

Errores comunes y soluciones

Para actualizaciones de atributos, prefiera query_selector() con un selector que apunte a un elemento editable. Para texto repetido o cambios a nivel de nodo, use query_selector_all() y procese cada nodo devuelto. Mantenga los selectores estables: los IDs son mejores para partes únicas de plantillas, las clases son útiles para etiquetas repetidas y los selectores restringidos ayudan a no cambiar elementos similares en otros grupos.

ProblemaSolución
Solo cambia un destinoquery_selector() devuelve solo la primera coincidencia. Use query_selector_all() para ediciones de varios nodos, como cambiar text_content; use query_selector() cuando el código deba llamar a set_attribute().
set_attribute() falla dentro de un bucle query_selector_all()Los elementos NodeList pueden no exponer Element.set_attribute(). Use ediciones a nivel de nodo como text_content, o use query_selector() cuando necesite establecer atributos.
El selector no devuelve nadaInspeccione el origen SVG y verifique ID, clase, nombre de etiqueta y valores de atributo reales.
El selector de atributo no coincideEmpiece con un selector de presencia de atributo como circle[fill], luego añada filtros de valor solo después de que el selector simple funcione.
Un selector de clase amplio cambia demasiadoAñada contexto, como #chart .bar[data-level='high'], para limitar la edición a un grupo.
El archivo de salida no cambióGuarde el documento editado y abra la ruta de salida, no el archivo de entrada original.

FAQ

¿Puedo usar selectores CSS para editar SVG en Python?

Sí. Cargue el SVG con SVGDocument, encuentre un destino editable con query_selector() y actualícelo con set_attribute(). Use query_selector_all() cuando necesite procesar todos los nodos coincidentes con una edición a nivel de nodo, como cambiar text_content.

¿Cuál es la diferencia entre query_selector() y query_selector_all()?

query_selector() devuelve el primer elemento coincidente y es la opción correcta cuando el código debe llamar a set_attribute(). query_selector_all() devuelve una NodeList de todas las coincidencias y es útil para ediciones a nivel de nodo, como cambiar text_content en cada nodo de texto coincidente.

¿Puedo seleccionar elementos SVG por clase?

Sí. Use un selector de clase como .label. Para varios nodos de texto, query_selector_all(".label") puede actualizar text_content en cada coincidencia. Para establecer atributos, use un selector restringido con query_selector().

¿Puedo seleccionar elementos SVG por atributos?

Sí. Los selectores de atributos como circle[fill] o .bar[data-level='high'] pueden apuntar a elementos SVG por atributos existentes. Limítelos con un ID de grupo cuando el mismo patrón aparezca en varios lugares.

¿Debo usar selectores CSS o XPath para editar SVG?

Use selectores CSS para IDs, clases, atributos y ediciones simples dentro de grupos. Use XPath cuando la consulta dependa de una estructura de documento más compleja o de relaciones entre nodos.

Artículos relacionados