JavaXML转换-奇怪的问题

JavaXML转换-奇怪的问题,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

我有一个奇怪的问题,我似乎无法解决。到目前为止,我的转换方法似乎工作得几乎完美无缺,但我目前正在构建的工具让我非常头疼

以下是我的方法:

这一个可以正常工作并生成正确的XML

    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);
    }