2016-05-21 5 views
0
セクションによるXMLのパースセクション

私のXMLファイルの短縮バージョンは次のようになります。SAXまたはStAXに

<?xml version="1.0" encoding="UTF-8"?> 
<MzIdentML id="MS-GF+"> 
    <SequenceCollection xmlns="http://psidev.info/psi/pi/mzIdentML/1.1"> 
     <DBSequence length="146" id="DBSeq143"> 
      <cvParam cvRef="PSI-MS" accession="MS:1001088"></cvParam> 
     </DBSequence> 
     <Peptide id="Pep7"> 
      <PeptideSequence>MFLSFPTTK</PeptideSequence> 
      <Modification location="1" monoisotopicMassDelta="15.994915"> 
       <cvParam cvRef="UNIMOD" accession="UNIMOD:35" name="Oxidation"></cvParam> 
      </Modification> 
     </Peptide> 
     <PeptideEvidence dBSequence_ref="DBSeq143" id="PepEv_160_1_18"></PeptideEvidence> 
     <PeptideEvidence dBSequence_ref="DBSeq143" id="PepEv_275_8_133"></PeptideEvidence> 
    </SequenceCollection> 
</MzIdentML> 

私は親の属性と子供separately.but DBSequence、ペプチドおよびPeptideEvidence詳細情報を取得したい(またはネストされました

:我々は <DBSequence>セクションを考慮すれば、例えば

---------------------------------------------------------------------- 
<DBSequence length="146" id="DBSeq143"> 
    <cvParam cvRef="PSI-MS" accession="MS:1001088"></cvParam> 
</DBSequence> 
---------------------------------------------------------------------- 
<Peptide id="Pep7"> 
    <PeptideSequence>MFLSFPTTK</PeptideSequence> 
    <Modification location="1" monoisotopicMassDelta="15.994915"> 
     <cvParam cvRef="UNIMOD" accession="UNIMOD:35" name="Oxidation"></cvParam> 
    </Modification> 
</Peptide> 
---------------------------------------------------------------------- 
<PeptideEvidence dBSequence_ref="DBSeq143" id="PepEv_160_1_18"></PeptideEvidence> 
<PeptideEvidence dBSequence_ref="DBSeq143" id="PepEv_275_8_133"></PeptideEvidence> 
---------------------------------------------------------------------- 

、:children..if私は怒鳴る示す各セクションのキーと値のペアとして、すべてのattribuesをしたい、つまり.IN)がありますこれは私がSAXで書いたコードです

DBSequence=>length=146;id=DBSeq143;cvRef=PSI-MS;accession=MS:1001088; 

:として

<DBSequence length="146" id="DBSeq143"> 
    <cvParam cvRef="PSI-MS" accession="MS:1001088"></cvParam> 
</DBSequence> 

が出力されなければならない

package lucene.parse; 

import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 
import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class MzIdentMLSAXParser extends DefaultHandler { 

    private boolean isDBsequence = false; 

    String DBSequenceSection; 
    String PeptideEvidenceDocument; 

    public static void main(String[] argv) throws SAXException, ParserConfigurationException, IOException { 
     MzIdentMLSAXParser ps = new MzIdentMLSAXParser("file_path_here/sample.xml"); 
    } 

    public MzIdentMLSAXParser(String dataDir) throws FileNotFoundException, SAXException, ParserConfigurationException, IOException { 

     FileInputStream fis = new FileInputStream(dataDir); 
     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     SAXParser parser = spf.newSAXParser(); 
     parser.parse(fis, this); 
    } 

    @Override 
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { 

     if (qName.equals("DBSequence")) { 
      // each time we found a new DBSequence, we re-initialize DBSequenceSection 
      DBSequenceSection = ""; 

      // get attributes of DBSequence 
      for (int i = 0; i < atts.getLength(); i++) { 
       DBSequenceSection += atts.getQName(i) + "=" + atts.getValue(i) + ";"; 
      } 
      isDBsequence = true; 
     } else if ((qName.equals("cvParam")) && (isDBsequence)) { 
      // get attributes of cvParam which are belongs to DBSequence 
      // there can be cvParam that are not belongs to DBSequence. 
      for (int i = 0; i < atts.getLength(); i++) { 
       DBSequenceSection += atts.getQName(i) + "=" + atts.getValue(i) + ";"; 
      } 
     } else if (qName.equals("PeptideEvidence")) { 
      // each time we found a new PeptideEvidence, we re-initialize docuDBSequenceSectionment 
      PeptideEvidenceDocument = ""; 

      for (int i = 0; i < atts.getLength(); i++) { 
       PeptideEvidenceDocument += atts.getQName(i) + "=" + atts.getValue(i) + ";"; 
      } 
     } 
    } 

    @Override 
    public void endElement(String uri, String localName, String qName) throws SAXException { 
     if (qName.equals("DBSequence")) { 
      System.out.println(qName +"=>"+DBSequenceSection); 
      isDBsequence = false; 
     } else if (qName.equals("PeptideEvidence")) { 
      System.out.println(qName +"=>"+PeptideEvidenceDocument); 
     } 
    } 
} 

これを行うのいずれかの簡単な方法はありますか?これはネストされたノードでこのようなタグがたくさんあるからです。ここでの挑戦はタグだけでなく、<Modification>などの他のタグにも現れます。私はStAXでも試しました。それはできませんでした。

+1

は、なぜそれがSAXやスタックスする必要がないOUTPUT、なぜあなたは、XPathやXQueryを使用することはできませんか? –

答えて

0

ここではStAXを使用した実例を示します。 StAXは既知のXML構造を解析する際に優れていますが、動的解析にも使用できます。

このコードは、知識に依存しています。 DBSequencePeptide、およびPeptideEvidenceのコンテンツと、PeptideSequenceのコンテンツにはテキストコンテンツが含まれていることがわかっていますが、他のコンテンツは含まれていません。

このメソッドは、XMLの構造に従うために再帰を使用します。

public static void main(String[] args) throws Exception { 
    String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
       "<MzIdentML id=\"MS-GF+\">\n" + 
       " <SequenceCollection xmlns=\"http://psidev.info/psi/pi/mzIdentML/1.1\">\n" + 
       "  <DBSequence length=\"146\" id=\"DBSeq143\">\n" + 
       "   <cvParam cvRef=\"PSI-MS\" accession=\"MS:1001088\"></cvParam>\n" + 
       "  </DBSequence>\n" + 
       "  <Peptide id=\"Pep7\">\n" + 
       "   <PeptideSequence>MFLSFPTTK</PeptideSequence>\n" + 
       "   <Modification location=\"1\" monoisotopicMassDelta=\"15.994915\">\n" + 
       "    <cvParam cvRef=\"UNIMOD\" accession=\"UNIMOD:35\" name=\"Oxidation\"></cvParam>\n" + 
       "   </Modification>\n" + 
       "  </Peptide>\n" + 
       "  <PeptideEvidence dBSequence_ref=\"DBSeq143\" id=\"PepEv_160_1_18\"></PeptideEvidence>\n" + 
       "  <PeptideEvidence dBSequence_ref=\"DBSeq143\" id=\"PepEv_275_8_133\"></PeptideEvidence>\n" + 
       " </SequenceCollection>\n" + 
       "</MzIdentML>"; 
    XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(new StringReader(xml)); 
    try { 
     reader.nextTag(); 
     search(reader); 
    } finally { 
     reader.close(); 
    } 
} 
private static void search(XMLStreamReader reader) throws XMLStreamException { 
    // reader must be on START_ELEMENT upon entry, and will be on matching END_ELEMENT on return 
    assert reader.getEventType() == XMLStreamConstants.START_ELEMENT; 
    while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) { 
     String name = reader.getLocalName(); 
     switch (name) { 
      case "DBSequence": 
      case "Peptide": 
      case "PeptideEvidence": { 
       Map<String, String> props = new LinkedHashMap<>(); 
       collectProps(reader, props); 
       System.out.println(name + ": " + props); 
       break; } 
      default: 
       search(reader); 
     } 
    } 
} 
private static void collectProps(XMLStreamReader reader, Map<String, String> props) throws XMLStreamException { 
    // reader must be on START_ELEMENT upon entry, and will be on matching END_ELEMENT on return 
    assert reader.getEventType() == XMLStreamConstants.START_ELEMENT; 
    for (int i = 0; i < reader.getAttributeCount(); i++) 
     props.put(reader.getAttributeLocalName(i), reader.getAttributeValue(i)); 
    String name = reader.getLocalName(); 
    switch (name) { 
     case "PeptideSequence": 
      props.put(name, reader.getElementText()); 
      break; 
     default: 
      while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) 
       collectProps(reader, props); 
    } 
} 

DBSequence: {length=146, id=DBSeq143, cvRef=PSI-MS, accession=MS:1001088} 
Peptide: {id=Pep7, PeptideSequence=MFLSFPTTK, location=1, monoisotopicMassDelta=15.994915, cvRef=UNIMOD, accession=UNIMOD:35, name=Oxidation} 
PeptideEvidence: {dBSequence_ref=DBSeq143, id=PepEv_160_1_18} 
PeptideEvidence: {dBSequence_ref=DBSeq143, id=PepEv_275_8_133} 
+0

スマートなソリューション!私はisCollectingというフラグを導入するだけで、SAXで作業しなければなりません。 STARTメソッドで興味のあるタグ(DBSequence、Peptideなど)が見つかった場合は、フラグをオンにして属性のコピーを開始します。 ENDメソッドで私の面白いタグを読んだときに消えました。どちらがいいですか? – user2125889

+0

@ user2125889あなたが一番好きな方。このような単純な動的解析では、SAXは問題ありません。より構造化された解析のためには、XML構造に従うためにコールスタックを使用して、各要素を解析するためのメソッドを記述できるので、StAXが優れています。これにより、異なる位置にある同じ名前の要素を異なるものとして容易に識別することができます。 SAXでは、そのような要素名の再利用が問題になります。 – Andreas

関連する問題