【问题标题】:Replacing a Namespace with XSLT用 XSLT 替换命名空间
【发布时间】:2010-03-21 11:03:33
【问题描述】:

您好,我想 work around a 'bug' in certain RSS-feeds,它为 mediaRSS 模块使用了不正确的命名空间。我尝试通过以编程方式操作 DOM 来做到这一点,但使用 XSLT 对我来说似乎更灵活。

例子:

<media:thumbnail xmlns:media="http://search.yahoo.com/mrss" url="http://www.suedkurier.de/storage/pic/dpa/infoline/brennpunkte/4311018_0_merkelxI_24280028_original.large-4-3-800-199-0-3131-2202.jpg" />
<media:thumbnail url="http://www.suedkurier.de/storage/pic/dpa/infoline/brennpunkte/4311018_0_merkelxI_24280028_original.large-4-3-800-199-0-3131-2202.jpg" />

命名空间必须是http://search.yahoo.com/mrss/(注意斜线)。

这是我的样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <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>

不幸的是,转换的结果是无效的 XML,我的 RSS-Parser (ROME Library) 不再解析提要:

java.lang.IllegalStateException: Root element not set
    at org.jdom.Document.getRootElement(Document.java:218)
    at com.sun.syndication.io.impl.RSS090Parser.isMyType(RSS090Parser.java:58)
    at com.sun.syndication.io.impl.FeedParsers.getParserFor(FeedParsers.java:72)
    at com.sun.syndication.io.WireFeedInput.build(WireFeedInput.java:273)
    at com.sun.syndication.io.WireFeedInput.build(WireFeedInput.java:251)
    ... 8 more

我的样式表有什么问题?

【问题讨论】:

    标签: xml xslt rss


    【解决方案1】:

    您的样式表中有一半的解决方案。

    您已放入模板以匹配(并更正)具有错误 Media RSS 命名空间的元素,但您没有任何内容可匹配 RSS 提要中的其他元素/属性。

    built-in template rules 匹配其余的文档节点,这只会将文本节点复制到输出中。这不会保留原始 RSS 提要的 XML,并且生成的输出不是有效的 RSS XML 结构。

    添加 identity transform 模板将确保将其他节点和属性复制到输出中并保留文档内容/结构。

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

    【讨论】:

    • 好的。我肯定需要在 XSL/XPATH 等方面投入更多时间!
    猜你喜欢
    • 2014-08-21
    • 2013-11-02
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    相关资源
    最近更新 更多