如何抑制java.xml Transformer添加到导入的外部系统实体的xml:base属性?

时间:2013-03-28 02:11:56

标签: java xml xslt dom xml-parsing

必须有一个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)));

    }

1 个答案:

答案 0 :(得分:2)

用于禁止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