【问题标题】:Java: Read XML files with dynamic structureJava:读取具有动态结构的 XML 文件
【发布时间】:2021-03-18 14:40:23
【问题描述】:

在我的项目中,我有几个具有不同结构的存储库 xml 文件。例如:

common.xml

<general>    
    <youTube>https://www.youtube.com/</youTube>     
    <eBay>https://www.ebay.com/</eBay>  
    <trollPic>https://mallofnorway.com/content/uploads/2020/07/008840118.jpg</trollPic>
    <ui>
        <multiValueAtt>Gender</multiValueAtt>
    </ui>
    <api>
        <ownerId>1e1b3a81-8f9a-4126-890a-109694e9fd7c</ownerId>
        <schemaId>4cbacf2e-8f3f-4c0b-9764-d88d302d279f</schemaId>
    </api>
</general>  

partner.xml

<general>
    <ui>
        <partner>
            <schema>
                <multiValueAttr>Gender</multiValueAttr>
            </schema>            
        </partner>
        <member>
            <schema>
                <multiValueAttr>Department</multiValueAttr>
            </schema>            
        </member>
    </ui>
</general>  

我需要创建一个函数来从所有这些文件中获取值。所以我知道我需要将我在该文件中查找的 xml 文件位置和指定的标记名称以及可能该标记/字符串的 xml 路径传递给我的函数。所以我猜方法调用应该看起来像getConfigParam('./some-file.xml', 'ui.partner.schema.multiValueAttr');
我知道如何阅读简单的xml 文件:

static public String objRepository(String fileName, String area, String key){
    try{
        String rootPath = Paths.get(".").toAbsolutePath().normalize().toString();
        String path = rootPath + "\\src\\main\\resources\\repository\\" + fileName + ".xml";
        File file=new File(path);
        DocumentBuilderFactory dbf= DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document doc=db.parse(file);
        doc.getDocumentElement().normalize();
        //System.out.println("The node name is: "+doc.getDocumentElement().getNodeName());

        NodeList nList=doc.getElementsByTagName(area);
        //System.out.println("The length is: "+nList.getLength());
        for(int i=0; i<nList.getLength(); i++){
            Node nNode=nList.item(i);
            if(nNode.getNodeType()==Node.ELEMENT_NODE){
                Element ele=(Element) nNode;
                return ele.getElementsByTagName(key).item(i).getTextContent();
            }
        }

    }catch(Exception e){
        e.printStackTrace();
    }
    return "";
}

我也知道how to read嵌套xml结构不变的文件,但我不知道如何用相同的方法读取不同结构的嵌套xml文件。

【问题讨论】:

  • 你看过 XPath 了吗?
  • 什么意思?

标签: java xml


【解决方案1】:

您应该看看 XPath。听起来您并不真正关心大部分内容,而只关心某些特定元素(您知道其中的路径)。 这意味着您可以简单地以通用方式读取 XML 并使用 XPath 提取您需要的值。以下是优秀(一如既往)Baeldung article 关于该主题的示例:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(this.getFile());
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Tutorials/Tutorial[@tutId=" + "'" + id + "'" + "]";
node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);

【讨论】:

  • 每次我只需要从 1 个特定文件中读取 1 个特定元素
  • 你知道那个元素在哪里吗?就像你上面写的,例如“ui.partner.schema.multiValueAttr”? XPath 应该适合您,只需将该路径改写为“/general/ui/partner/schema/multiValueAttr”并尝试上面的代码。
  • 您已经非常接近使用 xpath 和 getConfigParam('./some-file.xml', 'ui.partner.schema.multiValueAttr'); 的想法了。第二个参数可以是您的 XPath 'path'。例如,首先使用文档结构,您可以使用字符串/general/api/ownerId/text() 查看:w3schools.com/xml/xpath_intro.asp
  • @SebastianHeikamp 1) 最后代码行中的node 没有在此处以及 Baildung 的文章中定义。 2)如何从那里提取字符串值?
  • 如果它确实是您的 XPath 指向的节点,您应该能够将其解析为 org.w3c.dom.Node。该类有一个名为 getNodeValue 的方法,它将为您提供 String 值。
【解决方案2】:

在这里推荐一个主要为 html 开发的解析器可能并不受欢迎,但如果我是你,我会看看 jsoup。它也可以很好地解析xml。在我看来,对于初学者来说,它比其他解析器更直观,并且非常适合小型 xml 文件。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;

public class Example {

    public static void main(String[] args) throws IOException {

        File partnerXML = new File("path to partner.xml");
        InputStream in = new FileInputStream(partnerXML);

        Document partnerDoc = Jsoup.parse(in, "UTF-8", "", Parser.xmlParser());
        for (Element e : partnerDoc.select("multiValueAttr")) {
            System.out.println(e.text());
        }
    }
}

mvn:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2023-04-10
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多