JavaXML转换-奇怪的问题
我有一个奇怪的问题,我似乎无法解决。到目前为止,我的转换方法似乎工作得几乎完美无缺,但我目前正在构建的工具让我非常头疼 以下是我的方法: 这一个可以正常工作并生成正确的XMLJavaXML转换-奇怪的问题,java,xml,xslt,transform,Java,Xml,Xslt,Transform,我有一个奇怪的问题,我似乎无法解决。到目前为止,我的转换方法似乎工作得几乎完美无缺,但我目前正在构建的工具让我非常头疼 以下是我的方法: 这一个可以正常工作并生成正确的XML public static void transform(String filename, String filePath, String stylesheetPath, String outputTo, boolean prettyPrint, boolean excludeDeclaration) throws
public static void transform(String filename, String filePath, String stylesheetPath, String outputTo, boolean prettyPrint, boolean excludeDeclaration) throws TransformerException, IOException {
if (!new File(outputTo).exists()) new File(outputTo).mkdir();
TransformerFactory factory = TransformerFactory.newInstance();
Source xsl = new StreamSource(new File(stylesheetPath));
Templates template = factory.newTemplates(xsl);
Transformer transformer = template.newTransformer();
if (!prettyPrint) {
transformer.setOutputProperty(OutputKeys.INDENT, "no");
} else {
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
}
if (excludeDeclaration) transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
Source xml = new StreamSource(new File(filePath + filename));
OutputStream outputStream = new FileOutputStream(outputTo + filename);
transformer.transform(xml, new StreamResult(outputStream));
outputStream.close();
}
使用相同的XSLT,下面生成的XML(或来自XML的内容)只包含文本节点(没有元素、属性等)
从我一直在做的所有搜索来看,第二种方法似乎没有任何错误,但它确实产生了一些奇怪的结果
示例结果(不幸的是,我无法发布实际数据,所以我只是用其他数据替换了文本)
默认情况下,DocumentBuilder不支持命名空间。您需要设置NamespaceAware(true)。如果没有名称空间感知,样式表中的模板规则将不匹配,因此默认模板规则将生效,并且这些规则只输出文本节点
请注意,创建DOM只是为了向XSLT提供输入,这是一个非常糟糕的想法;使用XSLT处理器的本机树表示几乎肯定会更好。当我忘记让XSL复制元素节点时,我就遇到了这种情况。您确定要将完全相同的XSL文件传递给这两种方法吗?@VGR是的,我绝对确定。既然
xmlDoc
的类型是org.w3c.Document
,那么我应该将DOMSource
更改为什么?我看到很多例子都是这样做的。如果你已经有了一个DOM,并且你一直在使用它,那么这就很好了。只是不要专门为了转换DOM而创建DOM。然而,我发现我的回答是错误的——您在完成转换后创建了DocumentBuilder,所以它不可能是罪魁祸首。可能您手中的DOM不是基于名称空间感知构建的。我读入了一个XML文件,但在转换它之前必须进行一些操作。我只是传递要转换的文档,而不是承受磁盘IO的成本。我创建的文档不知道名称空间,因此如果您所说的是真的,那么我想这很可能是罪魁祸首。我会尝试一下,但可能需要几天的时间来测试和响应。谢谢你的建议。我对Java和XML处理还是相当陌生的,仍然有一个巨大的学习曲线。非常感谢您提供的任何帮助或建议。首先,我建议您使用XSLT(或XQuery)而不是Java进行“操作”。如果做不到这一点,我建议优先使用XOM、JDOM2或Axiom等现代树模型,而不是DOM:更新的模型在各个方面都更可取。通过操纵,我的意思是有时我必须组合XML文件才能进行转换,而且大多数时候我必须从电子表格收集信息并将其插入XML。这听起来很奇怪,但事实就是这样。我一定会研究XOM、JDOM2和Axiom,看看如何使用它们而不是DOM。再次感谢你的建议。
public static Document transformInMemory(Document xmlDoc, String stylesheetPath) throws TransformerException, ParserConfigurationException, SAXException, IOException {
TransformerFactory factory = TransformerFactory.newInstance();
Source xsl = new StreamSource(new File(stylesheetPath));
Templates template = factory.newTemplates(xsl);
Transformer transformer = template.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "0");
DOMSource source = new DOMSource(xmlDoc);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transformer.transform(source, new StreamResult(baos));
System.out.println(baos.toString());
// load into DocumentBuilder
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
InputSource is = new InputSource(new ByteArrayInputStream(baos.toByteArray()));
return builder.parse(is);
}
<?xml version="1.0" encoding="UTF-8"?>
Some Text Here
A.
Some other text here
B.
Some more text here
C.
And more text here
D.
Even more text here
A
1
public static Document transformInMemory(Document xmlDoc, String stylesheetPath) throws TransformerException, ParserConfigurationException, SAXException, IOException {
TransformerFactory factory = TransformerFactory.newInstance();
Source xsl = new StreamSource(new File(stylesheetPath));
Templates template = factory.newTemplates(xsl);
Transformer transformer = template.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "0");
// convert the xmlDoc to an inputstream
ByteArrayOutputStream xmlOutStream = new ByteArrayOutputStream();
Source domSource = new DOMSource(xmlDoc);
Result result = new StreamResult(xmlOutStream);
TransformerFactory.newInstance().newTransformer().transform(domSource, result);
InputStream in = new ByteArrayInputStream(xmlOutStream.toByteArray());
//DOMSource source = new DOMSource(xmlDoc);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Source source = new StreamSource(in);
transformer.transform(source, new StreamResult(baos));
System.out.println("baos -> " + baos.toString());
// load into DocumentBuilder
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
InputSource is = new InputSource(new ByteArrayInputStream(baos.toByteArray()));
return builder.parse(is);
}