【问题标题】:How can I suppress xml:base attribute that the java.xml Transformer is adding to imported external system entities?如何抑制 java.xml Transformer 添加到导入的外部系统实体的 xml:base 属性?
【发布时间】:2013-03-28 02:11:55
【问题描述】:

这必须有一个 xslt 或 xalan 属性,但我找不到它。

假设我有一个声明外部系统实体的 xml 文件:

<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE stuff [
        <!ENTITY imported_fragment SYSTEM "fragment.xml">
        ]>
<stuff>
    <innerstuff name="a">
        <lala>Hello!</lala>
    </innerstuff>

    &imported_fragment;
</stuff>

片段看起来像:

<innerstuff name="b">
    <lala>Bye!</lala>
</innerstuff>

如果我用 javax.xml 类读入并写回它,我会得到:

 <?xml version="1.0" standalone="yes" ?>
<stuff>
    <innerstuff name="a">
        <lala>Hello!</lala>
    </innerstuff>

    <innerstuff name="b" xml:base="file:/full/path/to/fragment.xml">
        <lala>Bye!</lala>
    </innerstuff>
</stuff>

注意它添加的属性xml:base。我该如何抑制这个?

这是我用来读写xml文件的代码:

    Document dom;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    try {
        db = dbf.newDocumentBuilder();
        sLogger.info("Parsing file: " + fInputFile);
        dom = db.parse(fInputFile);
    } catch (SAXException | IOException | ParserConfigurationException e) {
       //...
    }

    try {
        Transformer tr = TransformerFactory.newInstance().newTransformer();
        tr.setOutputProperty(OutputKeys.INDENT, "yes");
        tr.setOutputProperty(OutputKeys.METHOD, "xml");
        tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tr.setOutputProperty(OutputKeys.STANDALONE, "yes");
        //tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        File outputFile = new File(fOutputDirectory, fInputFile.getName());
        sLogger..info("Writing xml output to: " + outputFile);

        tr.transform(new DOMSource(dom), 
                 new StreamResult(new FileOutputStream(outputFile)));

    } catch (IOException | TransformerException e) {
        //...
    }

编辑:joepie 的回答有效。这是包含他的 XSLT 的 java 代码

     try {
        Transformer tr = TransformerFactory.newInstance().newTransformer();
        DOMResult domResult = new DOMResult();
        tr.transform(new DOMSource(dom), domResult);

        StreamSource source = new StreamSource(getClass().getResourceAsStream("removexmlbase.xslt"));
        Transformer tr2 = TransformerFactory.newInstance().newTransformer(source);
        tr2.setOutputProperty(OutputKeys.INDENT, "yes");
        tr2.setOutputProperty(OutputKeys.METHOD, "xml");
        tr2.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tr2.setOutputProperty(OutputKeys.STANDALONE, "yes");
        //tr2.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        File outputFile = new File(fOutputDirectory, fXMLFile.getName());
        getLog().info("Writing xml output to: " + outputFile);
        // send DOM to file
        tr2.transform(new DOMSource(domResult.getNode()), new StreamResult(new FileOutputStream(outputFile)));

    }

【问题讨论】:

    标签: java xml xslt dom xml-parsing


    【解决方案1】:

    一个抑制 xml:base 属性的 XSLT 1.0 模板:

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output indent="yes"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <!-- Suppress xml:base attributes -->
        <xsl:template match="@xml:base"/>
    
    </xsl:transform>
    

    Working Example

    【讨论】:

    • 谢谢,这行得通,我能够将它合并到我的 java 中。
    • 请注意,这意味着 xml:base 不是由 Transformer 添加的,而是由解析器添加的。
    猜你喜欢
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2014-05-14
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多