可以使用哪些方法从Java文件中返回有效和无效的XML数据?

可以使用哪些方法从Java文件中返回有效和无效的XML数据?,java,xml,xslt,jaxb,xquery,Java,Xml,Xslt,Jaxb,Xquery,我有以下应该是XML的数据: <?xml version="1.0" encoding="UTF-8"?> <Product> <id>1</id> <description>A new product</description> <price>123.45</price> </Product> <Product> <id>1<

我有以下应该是XML的数据:

<?xml version="1.0" encoding="UTF-8"?>
<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<ProductTTTTT>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</ProductAAAAAA>
无效节点:
..
..

然后我在思考如何使用JAVA(而不是web)实现这一点

  • 如果我没有错,那么用XSD验证它将使整个文件无效,因此不是一个选项
  • 使用默认的JAXB解析器(解组器)将导致上面的项,因为它在内部创建了我的实体的XSD
  • 使用XPathJust(据我所知)只会返回整个文件,我没有找到一种方法来获得像get这样的东西!有效(只是为了解释…)
  • 使用XQuery(可能?)。。顺便问一下,如何将XQuery与JAXB结合使用
  • XSL(T)将在XPath上产生同样的结果,因为它使用XPath来选择内容

所以。。。我可以使用哪种方法来实现目标?(如果可能,请提供链接或代码)

首先,您混淆了有效和格式正确。你说你想找到无效的元素,但是你的例子不仅仅是无效的,它们的格式是错误的。这意味着XML解析器除了向您抛出错误消息之外,不会对它们做任何事情。不能使用JAXB、XPath、XQuery、XSLT或任何东西来处理非XML的内容


您会说“很遗憾,我无法访问发送此xml格式的系统”。我不知道为什么称它为XML格式:它不是。我也不明白为什么你(和StackOverflow上的许多其他人)准备花时间像这样挖垃圾,而不是告诉发件人一起行动。如果给你一份有蛆的沙拉,你会试着把它们挑出来,还是把它送回去替换?你应该对坏数据采取零容忍的方法;这是发件人学习提高质量的唯一方法。

如果文件中包含以“产品”开头的带有开始和结束标记的行,您可以:


  • 使用文件扫描程序将此文档拆分为各个部分每当一行以
    开头时,根据定义,XML文件只能有一个。正如@MickMnemonic所说,将XML清理为只有一个根元素将解决您的一些(全部?)问题。我理解并同意你们两人的看法,但不幸的是,我无法访问发送这种xml格式的系统。还有其他选择吗?当你被告知它不是XML格式时,为什么要将它称为XML格式?这只是一种引用“东西”的方式……我完全理解并同意你的意见(我来这里之前已经尝试过),他们应该为我发送好的数据,但不幸的是,我没有这个选择。所以,让我们面对现实吧,否则我会按照老板的要求去做,或者被炒鱿鱼,就像这样简单。这有点令人沮丧。。。无论如何,对不起,伙计,但我不能接受这个问题的答案。你的答案讲述了一个非常有趣和重要的观点,每个开发人员都应该这样做,所以我把它标记为有用的。谢谢工程师们按照老板(或客户)的要求毫无疑问地去做,结果却要为格伦菲尔这样的灾难负责。嗨@Mads Hansen,谢谢你在这里帮助我。。。有了您(和其他人)的答案,我可以理解这并没有正确的方法,因为它不是xml。不管怎样,我在想你写的东西。唯一需要注意的是,你只是在验证你也可以调整该策略来规范这些结束元素,因此如果它以
    开始,请确保不仅是你,而且@Michael Kay帮助了我,即使有这种攻击性,我也理解他的意图。
    
    <Product>
       ...
    </Product>
    
    package com.stackoverflow.questions.52012383;
    
    import org.w3c.dom.Document;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.StringReader;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class FileSplitter {
    
        public static void parseFile(File file, String elementName) 
          throws ParserConfigurationException, IOException {
    
            List<Document> good = new ArrayList<>();
            List<String> bad = new ArrayList<>();
    
            String start-tag = "<" + elementName;
            String end-tag = "</" + elementName;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            StringBuffer buffer = new StringBuffer();
            String line;
            boolean append = false;
    
            try (Scanner scanner = new Scanner(file)) {
                while (scanner.hasNextLine()) {
                    line = scanner.nextLine();
    
                    if (line.startsWith(startTag)) {
                        append = true; //start accumulating content
                    } else if (line.startsWith(endTag)) {
                        append = false;
                        buffer.append(line); 
                        //instead of the line above, you could hard-code the ending tag to compensate for bad data:
                        // buffer.append(endTag + ">");
    
                        try { // to parse as XML
                            builder = factory.newDocumentBuilder();
                            Document document = builder.parse(new InputSource(new StringReader(buffer.toString())));
                            good.add(document); // parsed successfully, add it to the good list
    
                            buffer.setLength(0); //reset the buffer to start a new XML doc
    
                        } catch (SAXException ex) {
                            bad.add(buffer.toString()); // something is wrong, not well-formed XML
                        }
                    }
    
                    if (append) { // accumulate content
                        buffer.append(line);
                    }
                }
                System.out.println("Good items: " + good.size() + " Bad items: " + bad.size());
                //do stuff with the good/bad results...
            }
        }
    
        public static void main(String args[]) 
          throws ParserConfigurationException, IOException {
            File file = new File("/tmp/test.xml");
            parseFile(file, "Product");
        }
    
    }