为什么 java 在解析这个 XML 时会保存空字符串?

Why would java save empty strings when parsing this XML?

我试图让 java 解析 XML 文件的行,当它发现该行包含特定单词时,从该元素中获取值。这都是通过字符串操作完成的。我已经在本地测试过,这可以使用它在最终将在服务器上查看的同一文件的副本。

但是,由于某些原因,当 运行 通过远程服务器时,它无法按预期工作。结果它只显示空字符串,而之前它在元素中显示文本。 运行 所在的服务器也正在主动读取此文件,但对于不同的进程,它应该只在 运行 时间读取一次。它还会打印出正确的行数,以表明它像以前一样看到了正确的值,并且可以将这些行完整地打印到日志文件中。

这是处理文件解析的函数:

private HashSet<String> parseFile() throws ProcessingException{
    String fileLocation = getInterfaceLocation();
    HashSet<String> fileMasks = new HashSet<String>();

    try {
        File file = new File(fileLocation);
        BufferedReader br = new BufferedReader(new FileReader(file));

        boolean inFileSet = false;

        String line = "";
        while((line = br.readLine()) != null) {
            if(line.toLowerCase().contains("<fileset")) {
                inFileSet = true;
                continue;
            }
            if(line.toLowerCase().contains("</fileset>")) {
                inFileSet = false;
            }

            if(inFileSet) {
                log(line);
                if(!line.toLowerCase().contains("<include")) {
                    continue;
                }
                else {
                    line = line.substring(line.indexOf("name=") + "name=".length() + 1);
                    line = line.substring(0, line.indexOf("\""));
                    log("Adding mask = ", line);
                    fileMasks.add(line);
                }
            }
        }
        br.close();
    } catch(IOException e) {
        throw new ProcessingException("Unable to open the TESTFILE.xml file",e);
    }
    return fileMasks;
}

这是它正在解析的 XML 文件的适用部分:

<fileset>             
    <include name="filetype1*.csv"/>
    <include name="filetype2*.csv"/>
    <include name="filetype3*.csv"/>
    <include name="filetype4*.csv"/>
    <include name="filetype5*.csv"/>
    <include name="filetype6*.csv"/>
    <include name="filetype7*.csv"/>
    <include name="filetype8*.csv"/>
    <include name="filetype9*.csv"/>
    <include name="filetype10*.csv"/>
    <include name="filetype11*.csv"/>
    <include name="filetype12*.csv"/>
    <include name="filetype13*.csv"/>
    <include name="filetype14*.csv"/>
</fileset>

在我的测试环境 (Windows 10) 中,我看到以下输出:

<include name="filetype1*.csv"/>
Adding mask = filetype1*.csv
<include name="filetype2*.csv"/>
Adding mask = filetype2*.csv
<include name="filetype3*.csv"/>
...
<include name="filetype14*.csv"/>
Adding mask = filetype14*.csv

在远程服务器的环境中我得到:

<include name="filetype1*.csv"/>
Adding mask = 
<include name="filetype2*.csv"/>
Adding mask = 
<include name="filetype3*.csv"/>
...
<include name="filetype14*.csv"/>
Adding mask = 

以下应该是您的 parseFile 方法的替代品,该方法使用 XPath 查找您要查找的数据。

XPath 表达式 //include[@name] 表示:"give me all <include> in the document regardless of location that have a name attribute"

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;

/* Other code here */

private HashSet<String> parseFile()
        throws ProcessingException
{
    String fileLocation = getInterfaceLocation();
    HashSet<String> fileMasks = new HashSet<>();

    File file = new File(fileLocation);

    try {
        // BEGIN: DOM Boilerplate
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        XPathFactory xPathfactory = XPathFactory.newInstance();
        XPath xpath = xPathfactory.newXPath();
        // END: DOM Boilerplate

        Document doc = builder.parse(file);

        XPathExpression includeQuery = xpath.compile("//include[@name]");
        NodeList includes = (NodeList) includeQuery.evaluate(doc, XPathConstants.NODESET);
        for (int i = 0; i < includes.getLength(); i++) {
            Element include = (Element) includes.item(i);
            fileMasks.add(include.getAttribute("name"));
        }
    } catch (Exception e) {
        throw new ProcessingException("Failed to parse file", e);
    }

    return fileMasks;
}