1

我正在尝试检测/解决RSS 元素中的这个错误。这意味着我必须找到错误的命名空间声明并将其值更改为正确的命名空间。例如:

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

一定是:

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

在给定 org.w3c.Document 的情况下,我该如何实现?

我的意思是发现了如何获取某个命名空间的所有元素:

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

        } 

所以现在我必须弄清楚如何通过 JAXP 更改节点的命名空间。

4

2 回答 2

1

您可能可以使用 XSLT 执行此操作,使用如下规则:

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

媒体绑定到“ http://search.yahoo.com/mrss ”。

您可能需要稍微调整语法,因为我在没有编译器帮助的情况下编写此代码。此外,您将得到的可能不是非常好的格式(许多元素上的命名空间声明),但它应该是本地正确的。

于 2010-03-14T22:06:59.963 回答
0

只是为了完整起见:

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

样式表:

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

特别感谢 Mads Hansen 对 XSLT 的帮助

于 2010-03-21T23:35:36.557 回答