在文件中拆分一个巨大的xml

时间:2012-04-16 17:27:18

标签: java xml unix informatica-powercenter

我们一直试图在文件中拆分一个巨大的7GB xml,到目前为止,所有选择的选项都没有用。让我解释一下:

有一个来自外部用户的文件,因此我们无法更改它。为了加载到数据库中,需要将其拆分。

检查后,informatica有~4400个端口,这意味着每个项目至少有4400个节点。该文件被剪切成11个不同的文件。



    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <file>
        <fileHeader>This has some information</fileHeader>
        <fileBody>
            <Item id="1">
                <definition>
                    <id>1</id>
                    <name>Something</name>
                    <description>This is a dummy</description>
                </definition>
                <raw_materials>
                    <material>
                        <name>polycarbonate</name>
                        <description>Something to describe</description>
                        <cost>24.33</cost>
                        <units>LB</units>
                    </material>
                    <material txt="this" />
                    <material txt="had to" />
                    <material txt="be splitted" />
                    <material txt="into 3" />
                    <material txt="different files"/>
                </raw_materials>
                <specs>
                    <rating_usa issuer_id="3">A</rating_usa>
                    <rating_cnd issuer_id="9">10</rating_cnd>
                    <rating_br issuer_id="5">24.12</rating_bra>
                </specs>
                <budget>
                    <budget_usa>
                        <amount>465</amount>
                        <currency>USD</currency>
                        <usd_vs>1</usd_vs>
                    </budget_usa>
                    <budget_cnd>
                        <amount>30</amount>
                        <currency>CND</currency>
                        <usd_vs>1.24</usd_vs>
                    </budget_cnd>
                    <budget_bra>
                        <amount>20</amount>
                        <currency>BRP</currency>
                        <usd_vs>17.31</usd_vs>
                    </budget_bra>
                </budget>
                <vendor>  
                    <id>1HR24ZA</id>
                    <vendorName>Vendor</vendorName>
                    <deliveryRate>9.5</deliveryRate>
                    <location>
                        <country>Italy</country>
                        <address>Lamborghini Str. 245</address>
                        <phone>1234</phone>                 
                    </location>
                </vendor>
                <taxes>
                    <tax>
                        <country>MEX</country>
                        <federal_pct>16</federal_pct>
                        <currency>MXN</currency>
                        <pct_price>5</pct_price>
                    </tax>
                    <tax txt="this also"/>
                    <tax txt="contains too"/>
                    <tax txt="much nodes"/>
                </taxes>
            </Item>
            <Item id="2">
            </Item>
        </fileBody>
    </file>


这里每个项目只有6个市长标签(定义,raw_materials,规格,预算,供应商,税收),但实际上它有9个。

原始映射是这样的:Source - &gt;来源限定符 - &gt;目标(XML)

为了尝试解决问题,设置已更改,但没有显着改善。之后,每个文件都放在任务中的工作流程中,并且所有任务都是并行放置的。最后一次,与原作一样。

之后,尝试了java。 DOM不是一个选项,因为它将文件加载到内存中。然后,尝试了SAX和StAX,StAX表现出比SAX更好的性能,所以我们走了那个方向。

值得一提的是有关informatica的最终文件,有类似的内容:



    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <file>
        <fileHeader>This has some information</fileHeader>
        <fileBody>
            <Item id="1">
                <raw_materials>
                    <material>
                        <name>polycarbonate</name>
                        <description>Something to describe</description>                    
                    </material>
                    <material txt="this" />
                    <material txt="is hardcore" />
                </raw_materials>          
    </file>


如您所见,您需要检查文件中的特定标记。因此,每当新标记出现时,您最终会检查大约200个标记,并且为要将该标记放入的每个文件执行此操作:



    public class XMLCopier implements javax.xml.stream.StreamFilter {
        static boolean allowStream = false;
        static boolean tagFinished = false;

        private static boolean isWithinValidTag = false;
        private static Map tagMap = new HashMap();
        private static String currentTag = "";

        public static void main(String[] args) throws Exception {        
            String filename = "/path/to/xml/xmlInput.xml";        
            String fileOutputName = "/path/to/target/finalXML.xml";
            try
            {

                XMLInputFactory xmlif = null;
                xmlif = XMLInputFactory.newInstance();          
                FileInputStream fis = new FileInputStream(filename);
                XMLStreamReader xmlr = xmlif.createFilteredReader(xmlif.createXMLStreamReader(fis),new XMLCopier());            

                OutputStream outputFile = new FileOutputStream(fileOutputName);                     
                XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();            
                XMLStreamWriter xmlWriter = outputFactory.createXMLStreamWriter(outputFile);

                while (xmlr.hasNext())          
                {               
                    write(xmlr, xmlWriter);             
                    xmlr.next();
                }
                write(xmlr, xmlWriter);                                 
                xmlWriter.flush();
                xmlWriter.close();          
                xmlr.close();
                outputFile.close();         
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        public boolean accept(XMLStreamReader reader) {
            int eventType = reader.getEventType();
            if ( eventType == XMLEvent.START_ELEMENT )
            {
                String currentName = reader.getLocalName();
                if (isWithinValidTag)
                    if ( ( (List)tagMap.get(currentTag) ).contains(currentName) )               
                    {   
                        allowStream = true;                 
                    }

                if ( tagMap.containsKey(currentName) )
                {   
                    isWithinValidTag = true;
                    currentTag = currentName;
                    allowStream = true;
                }
            }
            return allowStream;
        }

        private void write(XMLStreamReader xmlr, XMLStreamWriter writer) throws XMLStreamException
        {
            switch (xmlr.getEventType()) {
                case XMLEvent.START_ELEMENT:
                    final String localName = xmlr.getLocalName();
                    writer.writeStartElement(localName);
                break;
            }
        }


当我们尝试在单个课程上进行操作时,我们以难以维护的代码结束,并且比信息解决过程花费的时间少了大约5分钟。然后我们将该类拆分为并行运行,但它看起来并不乐观,因为它比信息过程少7分钟,可能是因为您在4400个节点上搜索了200个标签。 11次。

正如你所看到的,这不是关于如何制作东西,而是关于如何快速制作东西。

您对我们如何改进文件拆分有任何想法吗?

PD。服务器有JVM 1.4.2,所以我们必须坚持这一点。 PD2。这里只显示一个项目,在真实文件中它有很多。

0 个答案:

没有答案