Pregunta

Estoy tratando de detetct / trabajo alrededor este error en elementos RSS. Eso significa que tengo que encontrar un espacio de nombres de declaración equivocada y cambiar su valor al espacio de nombres correcto. Por ejemplo:

xmlns:media="http://search.yahoo.com/mrss" 

debe ser:

xmlns:media="http://search.yahoo.com/mrss/" 

¿Cómo puedo achive que le da un org.w3c.Document?

Me Meanwile descubrí cómo conseguir todos los elementos de un determinado espacio de nombres:

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        XPathExpression expr = xpath.compile("//*[namespace-uri()='http://search.yahoo.com/mrss']");


        Object result = expr.evaluate(d, XPathConstants.NODESET);
        if (result != null) {
            NodeList nodes = (NodeList) result;
            for(int node=0;node<nodes.getLength();node++)
            {
                Node n = nodes.item(node);
                this.log.warn("Found old mediaRSS namespace declaration: "+n.getTextContent());
            }

        } 

Así que ahora tengo que encontrar la manera de cambiar el espacio de nombres de un nodo a través de JAXP.

¿Fue útil?

Solución 2

Sólo por el bien de la integridad:

Código Java:

Document d = out.outputW3CDom(converted);
            DOMSource oldDocument = new DOMSource(d);
            DOMResult newDocument = new DOMResult();
            TransformerFactory tf = TransformerFactory.newInstance();
            StreamSource xsltsource = new StreamSource(
                    getStream(MEDIA_RSS_TRANSFORM_XSL));
            Transformer transformer = tf.newTransformer(xsltsource);
            transformer.transform(oldDocument, newDocument);

private InputStream getStream(String fileName) {
    InputStream xslStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("/" + fileName);
    if (xslStream == null) {
        xslStream = Thread.currentThread().getContextClassLoader()      .getResourceAsStream(fileName);
        }
        return xslStream;
    }

hoja de estilo:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!--identity transform that will copy matched node/attribute to the output and apply templates for it's children and attached attributes-->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|*|text()" />
        </xsl:copy>
    </xsl:template>

    <!--Specialized template to match on elements with the incorrect namespace and generate a new element-->
    <xsl:template match="//*[namespace-uri()='http://search.yahoo.com/mrss']">
        <xsl:element name="{local-name()}" namespace="http://search.yahoo.com/mrss/" >
            <xsl:apply-templates select="@*|*|text()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Gracias especiales a Mads Hansen por su ayudar a con el XSLT.

Otros consejos

Probablemente se podría hacer con XSLT, con una regla como la siguiente:

<xsl:template match="media:*">
   <xsl:element name="local-name()" namespace="http://search.yahoo.com/mrss/">
      <xsl:apply-templates match="node()|@*"/>
   </xsl:element>
</xsl:template>

donde los medios de comunicación está obligado a " http://search.yahoo.com/mrss ".

Es posible que tenga que ajustar la sintaxis un poco, ya que estoy escribiendo esto sin la ayuda de un compilador. Además, lo que se obtiene no es probablemente muy bien formateada (declaraciones de espacios de muchos elementos), pero debe ser locically correcta.

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