java transformerfactory_java – 有可能避免使用xalan TransformerFactory吗?

我有以下代码:

final TransformerFactory factory = TransformerFactory.newInstance();

factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");

第二行在现代JDK(我试过1.8)中使用默认的TransformerFactory工作正常.但是当我将xalan(版本2.7.2,最新的版本)添加到classpath时,我在第二行上得到以下内容:

Exception in thread "main" java.lang.IllegalArgumentException: Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD

at org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:571)

at Main.main(Main.java:11)

我想这是因为xalan的TransformerFactory不支持这个属性. Xalan的实现通过ServiceLoader机制获取:它在xalan jar中的services / javax.xml.transform.TransfomerFactory中指定.

可以使用javax.xml.transform.TransformerFactory系统属性或$JRE / lib / jaxp.properties文件覆盖TransformerFactory实现,或直接在代码中传递类名.但要做到这一点,我必须提供一个具体的类名.现在,它是com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl,但在系统属性中对它进行硬编码有点可怕,因为在JDK升级时它们可以轻松更改类名,而我们只会得到运行时错误.

有没有办法指示TransformerFactory.newInstance()忽略xalan提供的实现?或者告诉它“只使用系统默认值”.

附:我不能只从类路径中删除xalan,因为我们使用的一堆其他库依赖于它.

最佳答案 我在这里唯一能做的就是硬编码JDK默认工厂并使用正常的发现过程作为后备:

TransformerFactory factory;

try {

factory = TransformerFactory.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl", SecureXmlFactories.class.getClassLoader());

} catch (Exception | TransformerFactoryConfigurationError e) {

LOGGER.error("Cannot load default TransformerFactory, let's try the usual way", e);

factory = TransformerFactory.newInstance();

}

然后在try / catch下配置它

// this works everywhere, but it does not disable accessing

// external DTDs... still enabling it just in case

try {

factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

} catch (TransformerConfigurationException e) {

LOGGER.error("Cannot enable secure processing", e);

}

// this does not work in Xalan 2.7.2

try {

factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");

} catch (Exception e) {

LOGGER.error("Cannot disable external DTD access", e);

}

// this does not work in Xalan 2.7.2

try {

factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

} catch (Exception e) {

LOGGER.error("Cannot disable external stylesheet access", e);

}

并监视日志以查看默认JDK工厂类名称是否/何时更改.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Java动态生成SiteMap.xml的问题,可以使用Java中的DOM(Document Object Model)技术来实现。以下是一些基本的步骤: 1. 创建一个XML文档对象模型(DOM)的实例。 2. 创建XML文档的根元素和其它需要的元素。 3. 将元素添加到DOM中。 4. 将DOM转换为XML格式并保存到文件中。 下面是一个简单的示例代码,可以参考: ```java import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; public class SiteMapGenerator { public static void main(String[] args) { try { // 创建DOM实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.newDocument(); // 创建根元素 Element root = doc.createElement("urlset"); root.setAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"); doc.appendChild(root); // 添加子元素 Element url = doc.createElement("url"); root.appendChild(url); Element loc = doc.createElement("loc"); loc.setTextContent("http://www.example.com/"); url.appendChild(loc); Element lastmod = doc.createElement("lastmod"); lastmod.setTextContent("2021-08-01"); url.appendChild(lastmod); // 将DOM转换为XML格式并保存到文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(new File("sitemap.xml")); transformer.transform(source, result); } catch (ParserConfigurationException | TransformerException e) { e.printStackTrace(); } } } ``` 这段代码会生成一个包含一个URL的SiteMap.xml文件,并保存在程序所在目录下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值