如何使用java将XML文件拆分为多个XML文件

如何使用java将XML文件拆分为多个XML文件,java,xml,Java,Xml,我第一次在Java中使用XML文件,我需要一些帮助。我正在尝试使用Java将一个XML文件拆分为多个XML文件 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <products> <product> <description>Sony 54.6" (Diag) Xbr Hx929 Internet Tv</description> &

我第一次在Java中使用XML文件,我需要一些帮助。我正在尝试使用Java将一个XML文件拆分为多个XML文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<products>
    <product>
        <description>Sony 54.6" (Diag) Xbr Hx929 Internet Tv</description>
        <gtin>00027242816657</gtin>
        <price>2999.99</price>
        <orderId>2343</orderId>
        <supplier>Sony</supplier>
    </product>
    <product>
        <description>Apple iPad 2 with Wi-Fi 16GB - iOS 5 - Black
        </description>
        <gtin>00885909464517</gtin>
        <price>399.0</price>
        <orderId>2343</orderId>
        <supplier>Apple</supplier>
    </product>
    <product>
        <description>Sony NWZ-E464 8GB E Series Walkman Video MP3 Player Blue
        </description>
        <gtin>00027242831438</gtin>
        <price>91.99</price>
        <orderId>2343</orderId>
        <supplier>Sony</supplier>
    </product>
    <product>
        <description>Apple MacBook Air A 11.6" Mac OS X v10.7 Lion MacBook
        </description>
        <gtin>00885909464043</gtin>
        <price>1149.0</price>
        <orderId>2344</orderId>
        <supplier>Apple</supplier>
    </product>
    <product>
        <description>Panasonic TC-L47E50 47" Smart TV Viera E50 Series LED
            HDTV</description>
        <gtin>00885170076471</gtin>
        <price>999.99</price>
        <orderId>2344</orderId>
        <supplier>Panasonic</supplier>
    </product>
</products>

索尼54.6英寸(Diag)Xbr Hx929互联网电视
00027242816657
2999.99
2343
索尼
配备16GB Wi-Fi的苹果iPad 2-iOS 5-黑色
00885909464517
399
2343
苹果
索尼NWZ-E464 8GB E系列随身听视频MP3播放器蓝色
00027242831438
91.99
2343
索尼
Apple MacBook Air一款11.6英寸Mac OS X v10.7版Lion MacBook
00885909464043
1149
2344
苹果
松下TC-L47E50 47英寸智能电视Viera E50系列LED
高清晰度电视
00885170076471
999.99
2344
松下
我尝试获取三个XML文档,如:

 <?xml version="1.0" encoding="UTF-8"?>
<products>
        <product>
            <description>Sony 54.6" (Diag) Xbr Hx929 Internet Tv</description>
            <gtin>00027242816657</gtin>
            <price currency="USD">2999.99</price>
            <orderid>2343</orderid>
        </product>
        <product>
            <description>Sony NWZ-E464 8GB E Series Walkman Video MP3 Player Blue</description>
            <gtin>00027242831438</gtin>
            <price currency="USD">91.99</price>
            <orderid>2343</orderid>
        </product>
</products>

索尼54.6英寸(Diag)Xbr Hx929互联网电视
00027242816657
2999.99
2343
索尼NWZ-E464 8GB E系列随身听视频MP3播放器蓝色
00027242831438
91.99
2343

每个供应商一个。我怎样才能收到它?这方面的任何帮助都将是巨大的

您可以在这里查看如何在Java中使用DOM解析XML文档:

在这里,如何编写新的XML文件:

此外,您还可以学习XPath以轻松选择节点:

如果性能不是您的目标,首先,加载DOM和Xpath后,可以使用以下Xpath查询检索xml文档中的所有供应商

//supplier/text()
你会得到这样的结果:

Text='Sony'
Text='Apple'
Text='Sony'
Text='Apple'
Text='Panasonic'
然后,我会把这些结果放在一个数组列表或其他任何东西中。第二步是该集合的迭代,并针对每个项目查询XML输入文档,以提取具有特定供应商的所有节点:

/products/product[supplier='Sony'] 
当然,在java中,您必须以动态方式构建最后一个xpath查询:

String xpathQuery = "/products/product/[supplier='" + currentValue + "']

之后,您将获得与指定供应商匹配的节点列表。下一步是构造新的XML DOM并将其保存在文件中。

DOM的另一种替代方法是,如果您有XML方言的模式(XSD),JAXB。

DOM解析器将消耗更多内存。我更喜欢使用SAX解析器来读写XML。

我喜欢Xmappr()的方法,您可以使用简单的注释:

首先是根元素Products,它只包含一个产品实例列表

@RootElement
public class Products {

    @Element
    public List<Product> product;
}
然后您只需从产品中获取产品实例:

public static void main(String[] args) throws FileNotFoundException {
    Reader reader = new FileReader("test.xml");
    Xmappr xm = new Xmappr(Products.class);
    Products products = (Products) xm.fromXML(reader);

    // fetch list of products
    List<Product> listOfProducts = products.product;

    // do sth with the products in the list
    for (Product product : listOfProducts) {
        System.out.println(product.description);
    }       
}
publicstaticvoidmain(字符串[]args)抛出FileNotFoundException{
Reader=newfilereader(“test.xml”);
Xmappr xm=新的Xmappr(Products.class);
Products=(Products)xm.fromXML(reader);
//获取产品列表
产品列表=products.product;
//用清单上的产品做某事
对于(产品:产品列表){
System.out.println(产品描述);
}       
}

然后,您可以对产品执行任何您想要的操作(例如,根据供应商对其进行排序并将其放入xml文件)

确保您将“inputFile”中的路径更改为您的文件以及输出部分:

StreamResult result = new StreamResult(new File("C:\xmls\" + supplier.trim() + ".xml"));
这是您的代码。

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

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

public class ExtractXml
{
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception
    {
        String inputFile = "resources/products.xml";

        File xmlFile = new File(inputFile);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // never forget this!

        XPathFactory xfactory = XPathFactory.newInstance();
        XPath xpath = xfactory.newXPath();
        XPathExpression allProductsExpression = xpath.compile("//product/supplier/text()");
        NodeList productNodes = (NodeList) allProductsExpression.evaluate(doc, XPathConstants.NODESET);

        //Save all the products
        List<String> suppliers = new ArrayList<String>();
        for (int i=0; i<productNodes.getLength(); ++i)
        {
            Node productName = productNodes.item(i);

            System.out.println(productName.getTextContent());
            suppliers.add(productName.getTextContent());
        }

        //Now we create the split XMLs

        for (String supplier : suppliers)
        {
            String xpathQuery = "/products/product[supplier='" + supplier + "']";

            xpath = xfactory.newXPath();
            XPathExpression query = xpath.compile(xpathQuery);
            NodeList productNodesFiltered = (NodeList) query.evaluate(doc, XPathConstants.NODESET);

            System.out.println("Found " + productNodesFiltered.getLength() + 
                               " product(s) for supplier " + supplier);

            //We store the new XML file in supplierName.xml e.g. Sony.xml
            Document suppXml = dBuilder.newDocument();

            //we have to recreate the root node <products>
            Element root = suppXml.createElement("products"); 
            suppXml.appendChild(root);
            for (int i=0; i<productNodesFiltered.getLength(); ++i)
            {
                Node productNode = productNodesFiltered.item(i);

                //we append a product (cloned) to the new file
                Node clonedNode = productNode.cloneNode(true);
                suppXml.adoptNode(clonedNode); //We adopt the orphan :)
                root.appendChild(clonedNode);
            }

            //At the end, we save the file XML on disk
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            DOMSource source = new DOMSource(suppXml);

            StreamResult result =  new StreamResult(new File("resources/" + supplier.trim() + ".xml"));
            transformer.transform(source, result);

            System.out.println("Done for " + supplier);
        }
    }

}
导入java.io.File;
导入java.util.ArrayList;
导入java.util.List;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.transform.OutputKeys;
导入javax.xml.transform.Transformer;
导入javax.xml.transform.TransformerFactory;
导入javax.xml.transform.dom.DOMSource;
导入javax.xml.transform.stream.StreamResult;
导入javax.xml.xpath.xpath;
导入javax.xml.xpath.XPathConstants;
导入javax.xml.xpath.XPathExpression;
导入javax.xml.xpath.XPathFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.Element;
导入org.w3c.dom.Node;
导入org.w3c.dom.NodeList;
公共类提取XML
{
/**
*@param args
*/
公共静态void main(字符串[]args)引发异常
{
字符串inputFile=“resources/products.xml”;
文件xmlFile=新文件(inputFile);
DocumentBuilderFactory dbFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder=dbFactory.newDocumentBuilder();
Document doc=dBuilder.parse(xmlFile);
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);//永远不要忘记这一点!
XPathFactory xfactory=XPathFactory.newInstance();
XPath=xfactory.newXPath();
XPathExpression allProductsExpression=xpath.compile(“//product/supplier/text()”);
NodeList productNodes=(NodeList)allProductsPression.evaluate(doc,XPathConstants.NODESET);
//保存所有产品
列出供应商=新建ArrayList();
对于(inti=0;i请考虑以下xml

<?xml version="1.0"?>
<SSNExportDocument xmlns="urn:com:ssn:schema:export:SSNExportFormat.xsd" Version="0.1" DocumentID="b482350d-62bb-41be-b792-8a9fe3884601-1" ExportID="b482350d-62bb-41be-b792-8a9fe3884601" JobID="464" RunID="3532468" CreationTime="2019-04-16T02:20:01.332-04:00" StartTime="2019-04-15T20:20:00.000-04:00" EndTime="2019-04-16T02:20:00.000-04:00">
    <MeterData MeterName="MUNI1-11459398" UtilDeviceID="11459398" MacID="00:12:01:fae:fe:00:d5:fc">
        <RegisterData StartTime="2019-04-15T20:00:00.000-04:00" EndTime="2019-04-15T20:00:00.000-04:00" NumberReads="1">
            <RegisterRead ReadTime="2019-04-15T20:00:00.000-04:00" GatewayCollectedTime="2019-04-16T01:40:06.214-04:00" RegisterReadSource="REG_SRC_TYPE_EO_CURR_READ" Season="-1">
                <Tier Number="0">
                    <Register Number="1" Summation="5949.1000" SummationUOM="GAL"/>
                </Tier>
            </RegisterRead>
        </RegisterData>
    </MeterData>
    <MeterData MeterName="MUNI4-11460365" UtilDeviceID="11460365" MacID="00:11:01:bc:fe:00:d3:f9">
        <RegisterData StartTime="2019-04-15T20:00:00.000-04:00" EndTime="2019-04-15T20:00:00.000-04:00" NumberReads="1">
            <RegisterRead ReadTime="2019-04-15T20:00:00.000-04:00" GatewayCollectedTime="2019-04-16T01:40:11.082-04:00" RegisterReadSource="REG_SRC_TYPE_EO_CURR_READ" Season="-1">
                <Tier Number="0">
                    <Register Number="1" Summation="136349.9000" SummationUOM="GAL"/>
                </Tier>
            </RegisterRead>
        </RegisterData>
    </MeterData>

到目前为止,您已经尝试了什么?Java在XML处理方面有很多机会。机会包括编组/解编组DOM模型、流XML读/写、运行XSLT转换等。我从来没有使用XSLT。我该怎么做?我需要在2小时内解决此问题。您可以帮我吗?请?:(我想按供应商对产品进行排序。我不知道怎么做。你可以给我一些代码吗?或者类似的东西…我想按供应商对产品进行排序。我不知道怎么做。你可以给我一些代码吗?或者类似的东西…我如何填充ArrayList?目前我有以下代码:String expSup=“//supplier/text()”String path=“myFile.xml”ArrayList suppliers=new ArrayList();Document xmlDocument=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(路径);XPath xPathSu
<?xml version="1.0"?>
<SSNExportDocument xmlns="urn:com:ssn:schema:export:SSNExportFormat.xsd" Version="0.1" DocumentID="b482350d-62bb-41be-b792-8a9fe3884601-1" ExportID="b482350d-62bb-41be-b792-8a9fe3884601" JobID="464" RunID="3532468" CreationTime="2019-04-16T02:20:01.332-04:00" StartTime="2019-04-15T20:20:00.000-04:00" EndTime="2019-04-16T02:20:00.000-04:00">
    <MeterData MeterName="MUNI1-11459398" UtilDeviceID="11459398" MacID="00:12:01:fae:fe:00:d5:fc">
        <RegisterData StartTime="2019-04-15T20:00:00.000-04:00" EndTime="2019-04-15T20:00:00.000-04:00" NumberReads="1">
            <RegisterRead ReadTime="2019-04-15T20:00:00.000-04:00" GatewayCollectedTime="2019-04-16T01:40:06.214-04:00" RegisterReadSource="REG_SRC_TYPE_EO_CURR_READ" Season="-1">
                <Tier Number="0">
                    <Register Number="1" Summation="5949.1000" SummationUOM="GAL"/>
                </Tier>
            </RegisterRead>
        </RegisterData>
    </MeterData>
    <MeterData MeterName="MUNI4-11460365" UtilDeviceID="11460365" MacID="00:11:01:bc:fe:00:d3:f9">
        <RegisterData StartTime="2019-04-15T20:00:00.000-04:00" EndTime="2019-04-15T20:00:00.000-04:00" NumberReads="1">
            <RegisterRead ReadTime="2019-04-15T20:00:00.000-04:00" GatewayCollectedTime="2019-04-16T01:40:11.082-04:00" RegisterReadSource="REG_SRC_TYPE_EO_CURR_READ" Season="-1">
                <Tier Number="0">
                    <Register Number="1" Summation="136349.9000" SummationUOM="GAL"/>
                </Tier>
            </RegisterRead>
        </RegisterData>
    </MeterData>
File xmlFile = new File("input.xml");
jaxbContext = JAXBContext.newInstance(SSNExportDocument.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
SSNExportDocument ssnExpDoc = (SSNExportDocument) jaxbUnmarshaller.unmarshal(xmlFile);
MeterData mD = new MeterData();
Map<String, List<MeterData>> meterMapper = new HashMap<String, List<MeterData>>(); // Phantom Reference

for (MeterData mData : ssnExpDoc.getMeterData()) {
            String meterFullName = mData.getMeterName();
            String[] splitMeterName = meterFullName.split("-");
            List<MeterData> _meterDataList = meterMapper.get(splitMeterName[0]);// o(1)
            if (_meterDataList == null) {
                _meterDataList = new ArrayList<>();
                _meterDataList.add(mData);
                meterMapper.put(splitMeterName[0], _meterDataList);
                _meterDataList = null;
            } else {
                _meterDataList.add(mData);
            }
        }
       JAXBContext jaxbContext = JAXBContext.newInstance(SSNExportDocument.class);

        // Create Marshaller
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        // Required formatting??
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        //jaxbMarshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);

        // Print XML String to Console

        StringWriter sw = new StringWriter();

        // Write XML to StringWriter
        jaxbMarshaller.marshal(employee, sw);

        // Verify XML Content
        String xmlContent = sw.toString();
        System.out.println(xmlContent);