【问题标题】:XMLStreamException: No element was found to write: ArrayIndexOutOfBoundsException while parsing xml file using StAXXMLStreamException:未找到要写入的元素:ArrayIndexOutOfBoundsException 使用 StAX 解析 xml 文件时
【发布时间】:2015-12-07 03:25:14
【问题描述】:

在下面的 xml 文件中,我在哈希图中(在源代码中命名为“ds”)中有文件名及其各自的规则编号,格式为 {{file1.c,{1234,3456,5087,9900,....}} ,{file2.c,{1234,3456,5087,9900,....}}>,如果对于 file1.c,给定列表中的任何规则编号存在于<QACRule> 标记的 xml 文件中(这里 5087 匹配)我想删除它的父节点,即<Complain>节点。

<SourceFiles>
    **<File name="file1.c">**
        <FileSummary>
            <QAC>
                <StatDev>0</StatDev>
                <StatIntendDev>1</StatIntendDev>
            </QAC>
            <Developer>
                <StatDev>0</StatDev>
                <StatIntendDev>0</StatIntendDev>
                <StatBlank>1</StatBlank>
            </Developer>
            <Total>
                <TotalRank>intended deviation</TotalRank>
                <StatDev>0</StatDev>
                <StatIntendDev>1</StatIntendDev>
            </Total>
        </FileSummary>
        **<Complain lfd="1">**
            <Line>43</Line>
            <Description>"#include statements"</Description>
            <Rule>
                **<QACRule>5087</QACRule>**
                <CodingStd>18.1.</CodingStd>
                <Deviation>true</Deviation>
            </Rule>
            <Ranking>
                <QACRank>intended deviation</QACRank>
                <DeveloperRank></DeveloperRank>
                <TotalRank>intended deviation</TotalRank>
            </Ranking>
            <Comment>these includes must stay here at this position</Comment>
        </Complain>
        **<Complain lfd="2">**
            <Line>140</Line>
            <Description>"#include statements"</Description>
            <Rule>
                **<QACRule>55555</QACRule>**
                <CodingStd>18.1.</CodingStd>
                <Deviation>true</Deviation>
            </Rule>
            <Ranking>
                <QACRank>intended deviation</QACRank>
                <DeveloperRank></DeveloperRank>
                <TotalRank>intended deviation</TotalRank>
             </Ranking>
             <Comment>these includes must stay here at this position</Comment>
        </Complain>
    </File>
    <File name="file2.c>
         ......
    </File>
</SourceFiles>         

但我不明白在检查 hashmap 中的 &lt;QACRule&gt; 值后,我该如何去删除 &lt;Complain&gt; 节点?

我尝试了以下 java 代码:

inFactory = XMLInputFactory.newInstance();
outFactory= XMLOutputFactory.newInstance();
eventReader = inFactory.createXMLEventReader(new FileReader(inputFilePath));
out=new FileOutputStream("C:\\Users\\uidg8154\\Desktop\\new.xml");
eventWriter= outFactory.createXMLEventWriter(out);
while(eventReader.hasNext()){
    XMLEvent event=eventReader.nextEvent();

    if(event.isStartElement() && event.asStartElement().getName().getLocalPart().equalsIgnoreCase("SourceFiles") ){
        isSourceFileParent=true;    
        System.out.println("-------start of <SourceFies>---------");
        srcFiles=new SourceFiles();
    }

    if(event.isEndElement() && event.asEndElement().getName().getLocalPart().equalsIgnoreCase("SourceFiles")){
        isSourceFileParent=false;
        System.out.println("-------end of <SourceFies>---------");

    }

    if(isSourceFileParent==true && event.isStartElement() && event.asStartElement().getName().getLocalPart().equalsIgnoreCase("File")){
            fileNameValue=event.asStartElement().getAttributeByName(new QName("name")).getValue();
        System.out.println(fileNameValue);
        sourceFileNamesFromInputXml.add(fileNameValue);
    }

    if(isSourceFileParent==true && event.isStartElement() && event.asStartElement().getName().getLocalPart().equalsIgnoreCase("Complain")){ 
        complainIdValue=event.asStartElement().getAttributeByName(new QName("lfd")).getValue();
        System.out.println(complainIdValue);
    }

    if(isSourceFileParent==true && event.isStartElement() && event.asStartElement().getName().getLocalPart().equalsIgnoreCase("QACRule")){ 
        event = eventReader.nextEvent();
        isQacRuleParent=true;
        isProceed=true;
        qacRuleNoValue=event.asCharacters().getData();
    }

    if(ds.containsKey(fileNameValue) && isProceed==true){
        qacRuleNos=ds.get(fileNameValue);
        if(qacRuleNos.contains(qacRuleNoValue)){
            isIgnoreComplainNode=true;
        }
    }

    if (isSourceFileParent==true && event.isEndElement() && event.asEndElement().getName().getLocalPart().equals("Complain") && isIgnoreComplainNode==true) {
        isIgnoreComplainNode=false;
    }

    if(isIgnoreComplainNode==false){
        System.out.println(event);
        eventWriter.add(event);
    }
}//end of while
eventWriter.flush();
eventWriter.close();

使用此代码,我面临“javax.xml.stream.XMLStreamException:找不到要写入的元素:java.lang.ArrayIndexOutOfBoundsException:-1”异常和奇怪的输出文件。

【问题讨论】:

    标签: java xml xml-parsing sax stax


    【解决方案1】:

    您正在同时进行 stax 解析和写入,您可能需要处理更多上下文。当您检测到isIgnoreComplainNode=true 时,已经为时已晚,因为您已经在输出中写入了对应的事件:

    <Complain lfd="1">
            <Line>43</Line>
            <Description>"#include statements"</Description>
            <Rule>
                <QACRule>
    

    如果你想在你的输出中避免这些事件,你应该在列表中收集&lt;Complain&gt;打开到&lt;/Complain&gt;闭包之间的事件,当你到达&lt;Complain&gt;闭包时:检查isIgnoreComplainNode

    • 如果为false,则将列表的所有事件添加到eventWriter中(顺序相同)
    • 如果为真,则什么也不做

    清空列表并继续解析。

    主要问题是“我怎样才能避免在我的输出中写入不需要的&lt;Complain&gt; 节点”,即“我怎样才能超越并删除&lt;Complain&gt; 节点”。如果把事件发给eventWriter,回来就来不及了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-17
      • 2011-08-24
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      相关资源
      最近更新 更多