2010-03-14 5 views
1

J'essaie de détecter/contourner this bug dans les éléments RSS. Cela signifie que je dois trouver une déclaration d'espace de nom incorrecte et modifier sa valeur pour l'espace de noms correct. Par exemple:Déclaration d'espace de noms XML fixe

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

doit être:

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

Comment puis-je achive que, étant donné un org.w3c.Document?

Je Meanwile trouvé comment obtenir tous les éléments d'un certain espace de noms:

 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()); 
      } 

     } 

Alors maintenant, je dois comprendre comment changer l'espace de noms d'un nœud via JAXP.

Répondre

0

Juste pour être complet:

code 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; 
    } 

Stylesheet:

<?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> 

Un grand merci à Mads Hansen pour son help avec le XSLT.

1

Vous pouvez probablement le faire avec XSLT, avec une règle comme ceci:

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

où les médias est lié à « http://search.yahoo.com/mrss ».

Vous devrez peut-être modifier un peu la syntaxe, car j'écris ceci sans l'aide d'un compilateur. En outre, ce que vous obtiendrez n'est probablement pas extrêmement bien formaté (déclarations d'espace de noms sur de nombreux éléments), mais il devrait être correct localement.

+0

Merci pour votre réponse. Cependant, j'accède au document au niveau de l'objet. Je ne suis pas sûr non plus si le préfixe local sera toujours "media:". Après tout ce sont RSS-Feeds faites par d'autres personnes. Dieu sait quel préfixe ils utilisent: -/ – er4z0r

+0

Ils ne doivent pas! Vous pouvez utiliser n'importe quel préfixe dans le XSLT (par exemple "x: *"), tout ce qui compte est l'espace de noms. (En d'autres termes, le préfixe que vous utilisez dans XSLT n'a rien à voir avec le préfixe dans le fichier XML.) –

+0

@ er4z0r - le préfixe d'espace de noms que vous déclarez dans votre XSLT (ie media) ne doit pas nécessairement correspondre au préfixe d'espace de noms dans le document source. Tant qu'ils se réfèrent tous les deux au même URI, le modèle correspondra. –

Questions connexes