es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Como traductor de español para documentos de TI, usaré etiquetas de entrada como etiquetas de cierre en la salida XML de XSLT.

Tengo un XML (sobre el cual no tengo control) que incluye algunas anotaciones “rdf”.
Estoy tratando de convertir esto en un RDF/XML útil (usando XSLT), pero hay un problema que no sé cómo resolver.
Primero, en el XML hay secciones largas como esta:

<rdf:description>
  <some:tag>
    <rdf:bag>
      <rdf:li rdf:resource="resource1"></rdf:li>
    </rdf:bag>
  </some:tag>
  <some:other-tag>
    <rdf:bag>
      <rdf:li rdf:resource="resource2"></rdf:li>
      <rdf:li rdf:resource="resource3"></rdf:li>
    </rdf:bag>
  </some:other-tag>
</rdf:description>

El objetivo es crear RDF/XML como este:

<rdf:description>
  <some:tag>resource1</some:tag>
  <some:other-tag>resource2</some:other-tag>
  <some:other-tag>resource3</some:other-tag>
</rdf:description>

Sin embargo, la cantidad de etiquetas diferentes potencialmente es ilimitada, por lo que no puedo enumerar diferentes casos aquí. Necesito una forma genérica de usar la etiqueta que rodea la bolsa como etiquetas de cierre para los atributos de recurso individuales.

Desafortunadamente, no sé mucho de XSLT, así que estoy perdido aquí.

Lo que he hecho hasta ahora desafortunadamente no funciona para el caso de “some:other-tag”, porque solo obtengo una tripleta en la que los objetos están concatenados:

<some:other-tag>resource2resource3</some:other-tag>
<xsl:template match="rdf:Description/*">
  <xsl:copy>
    <xsl:for-each select="rdf:Bag/rdf:li/@rdf:resource">
      <xsl:value-of select="."></xsl:value-of>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema, puedes hacer uso de la función de creación dinámica de elementos de XSLT junto con la función name().

    Aquí tienes un ejemplo de código XSLT que debería funcionar:

    <xsl:template match="rdf:Description/*">
      <xsl:copy>
        <xsl:for-each select="*">
          <xsl:variable name="enclosing-tag" select="name(..)"></xsl:variable>
          <xsl:for-each select="rdf:Bag/rdf:li/@rdf:resource">
            <xsl:element name="{$enclosing-tag}">
              <xsl:value-of select="."></xsl:value-of>
            </xsl:element>
          </xsl:for-each>
        </xsl:for-each>
      </xsl:copy>
    </xsl:template>
    

    Así es cómo funciona:

    • El atributo match del elemento xsl:template está configurado como rdf:Description/*, lo que significa que esta plantilla se aplicará a cualquier elemento hijo directo de rdf:Description.
    • Dentro de la plantilla, utilizamos un bucle for-each para iterar sobre todos los elementos hijos del elemento actual.
    • Utilizamos la función name(..) para obtener el nombre del elemento padre (es decir, el que encierra al elemento rdf:Bag).
    • Dentro del bucle, utilizamos otro bucle for-each para iterar sobre todos los elementos rdf:li y sus valores de atributo rdf:resource.
    • Utilizamos el elemento xsl:element para crear dinámicamente un elemento con el mismo nombre que el elemento que encierra (padre).
    • Utilizamos el elemento xsl:value-of para mostrar el valor del atributo rdf:resource como contenido de texto del elemento creado dinámicamente.

    Esto debería generar la salida deseada de RDF/XML para cualquier número de etiquetas diferentes.

Comments are closed.