繁体   English   中英

stax xml与getname函数的混淆

[英]stax xml confusion with getname function

我有一个这样的xml文件:

<comment type="PTM">
    <text evidence="19">Sumoylated following its interaction with PIAS1 and UBE2I.</text>
</comment>
<comment type="PTM">
    <text evidence="17">Ubiquitinated, leading to proteasomal degradation.</text>
</comment>
<comment type="disease">
    <text>A chromosomal aberration involving ZMYND11 is a cause of acute poorly differentiated myeloid leukemia. Translocation (10;17)(p15;q21) with MBTD1.</text>
</comment>
<comment type="disease" evidence="23">
    <disease id="DI-04257">
        <name>Mental retardation, autosomal dominant 30</name>
        <acronym>MRD30</acronym>
        <description>A disorder characterized by significantly below average general intellectual functioning associated with impairments in adaptive behavior and manifested during the developmental period. MRD30 patients manifest mild intellectual disability and subtle facial dysmorphisms, including hypertelorism, ptosis, and a wide mouth.</description>
        <dbReference type="MIM" id="616083"/>
    </disease>
    <text>The disease is caused by mutations affecting the gene represented in this entry.</text>
</comment>
<comment type="similarity">
    <text evidence="8">Contains 1 bromo domain.</text>
</comment>
<comment type="similarity">
    <text evidence="9">Contains 1 MYND-type zinc finger.</text>
</comment>

我使用stax提取疾病信息。 这是我的代码的一部分:

XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader( new FileReader(p)); 

            while(eventReader.hasNext()){
               XMLEvent event = eventReader.nextEvent();
               switch(event.getEventType()){
                  case XMLStreamConstants.START_ELEMENT:
                     StartElement startElement = event.asStartElement();
                     String qName = startElement.getName().getLocalPart();
                     if (qName.equalsIgnoreCase("comment")) {
                        System.out.println("Start Element : comment");
                        Iterator<Attribute> attributes = startElement.getAttributes();
                        Attribute a = attributes.next(); 
                         System.out.println("ATRIBUTES " + a.getName());
                        type = a.getValue();
                        System.out.println("Roll No : " + type);
                     }  else if(qName.equalsIgnoreCase("text") && type.equals("disease")){ text = true; } 

                     break;

                    case XMLStreamConstants.CHARACTERS:
                     Characters characters = event.asCharacters();
                     if(text){ res = res + " " + characters.getData(); 
                        //System.out.println("TEXT: " + res);
                        text = false;
                     }
                    break;

                  case  XMLStreamConstants.END_ELEMENT:
                     EndElement endElement = event.asEndElement();
                     if(endElement.getName().getLocalPart().equalsIgnoreCase("comment")){
                        //System.out.println("End Element : comment"); 
                        //System.out.println();
                     }
                     break; 

对于这种类型的线:

<comment type="disease">

我可以正确提取信息,但是当我尝试在此行中找到评论类型“疾病”时:

<comment type="disease" evidence="23">

它给了我type = evidence,而不是type = disease。 因此,它不会从此类行中保存任何内容。

很抱歉,没有直接答案,只是对如何有效使用StaX或XmlPull进行了评论:流XML解析器旨在对递归下降解析很友好(避免使用显式状态建模,这是SAX解析器经常需要的功能)我希望使用以下方法(拒绝或忽略所有意外内容):

Comment parseComment(XMLEventReader eventReader) {
   // call parseText and parseDisease for the corresponding element starts
}

Text parseText(XMLEventReader eventReader) {
}

Disease parseDisease(XmlEventReader eventReader) {
} 

就是说,这是一个折衷方案:如果不需要流方面(性能),则最好是解析为DOM,然后根据需要通过走入或窥视DOM来提取信息,从而避免了低级操作。级别的XML API。

首先我们可以养成使用有用的变量名的习惯,您可以使用以下变量及其类型: a (节点), text (布尔值), qName (字符串)...这些变量让我me不休。想知道它们是什么:

a -只要不是一个有用的名字,它应该是这样的typeAttr或东西提的是,它应该是type=""属性

text -是布尔值? 也许collectText会更合适,因为它指定您应该收集下一个文本事件值。

qName -它是一个字符串,它是localPart一个QName的,如果它不是一个QName那么不要将其命名为一个..


但这足以使您理解。 您的问题在于获取属性的位置。 在XML中,属性没有特定的顺序,并且不会也不应期望它们按定义的顺序返回。 在您的代码中,您具有以下内容

Iterator<Attribute> attributes = startElement.getAttributes();
Attribute a = attributes.next(); 
System.out.println("ATRIBUTES " + a.getName());
type = a.getValue();

在这里,您从元素获得第一个属性,并将类型设置为其值。 正如我提到的,XML属性没有特定的顺序,因此您将获得evidence属性。 您应该通过名称获取属性:

Attribute a = startElement.getAttributeByName(QName.valueOf("type"));
System.out.println("ATRIBUTES " + a.getName());
type = a.getValue();

通过使用Stax,我假设您正在处理大型文档或资源有限的平台……事实是内存开销在很大程度上是与DOM相关的问题。 另一方面,VTD-XML比DOM高效得多,同时保留了DOM编码风格的所有优点...请阅读此最新研究论文以了解更多信息

http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf

import com.ximpleware.*;
public class queryAttr {
    public static void main(String[] s) throws VTDException{
        VTDGen vg = new VTDGen();
        vg.selectLcDepth(5);// improve XPath performance for deep document
        if (!vg.parseFile("input.xml", false))
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/root/comment[@type='disease' and @evidence='23']");
        int i=0,j=0;
        while((i=ap.evalXPath())!=-1){
            if (vn.toElement(VTDNav.FIRST_CHILD)){
                System.out.println(" element name: "+ vn.toString(vn.getCurrentIndex()));
                j=vn.getText();
                if (i!=-1)
                    System.out.println(""+vn.toString(i));
                if (vn.toElement(VTDNav.NS)){
                    System.out.println(" element name: "+ vn.toString(vn.getCurrentIndex()));
                    j=vn.getText();
                    if (i!=-1)
                        System.out.println("text node==>"+vn.toString(i));
                }
                if (vn.toElement(VTDNav.NS)){
                    System.out.println(" element name: "+ vn.toString(vn.getCurrentIndex()));
                    j=vn.getText();
                    if (i!=-1)
                        System.out.println("text node==>"+vn.toString(i));
                }
                if (vn.toElement(VTDNav.NS)){
                    System.out.println(" element name: "+ vn.toString(vn.getCurrentIndex()));
                    j=vn.getText();
                    if (i!=-1)
                        System.out.println("text node==>"+vn.toString(i));
                }
                vn.toElement(VTDNav.PARENT);
            }

        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM