Проблемы с получением правильных элементов из XML - PullRequest
0 голосов
/ 05 июня 2019

У меня есть следующий xml:

 <TEI>
  <xi:include href="header.xml"/>
  <text>
   <body>
    <!-- morph_1-p is akapit 7300 with instances (akapit_transzy-s) 14598, 14618 in batches (transza-s) 1461, 1463 resp. -->
    <p corresp="ann_segmentation.xml#segm_1-p" xml:id="morph_1-p">
     <s corresp="ann_segmentation.xml#segm_1.35-s" xml:id="morph_1.35-s">
      <seg corresp="ann_segmentation.xml#segm_1.1-seg" xml:id="morph_1.1-seg">
       <fs type="morph">
        <f name="orth">
         <string>Sami</string>
        </f>
        <!-- Sami [0,4] -->
        <f name="interps">
         <fs type="lex" xml:id="morph_1.1.1-lex">
          <f name="base">
           <string>sam</string>
          </f>
          <f name="ctag">
           <symbol value="adj"/>
          </f>
          <f name="msd">
           <vAlt>
            <symbol value="pl:nom:m1:pos" xml:id="morph_1.1.1.1-msd"/>
            <symbol value="pl:voc:m1:pos" xml:id="morph_1.1.1.2-msd"/>
           </vAlt>
          </f>
         </fs>
        </f>
        <f name="disamb">
         <fs feats="#an8003" type="tool_report">
          <f fVal="#morph_1.1.1.1-msd" name="choice"/>
          <f name="interpretation">
           <string>sam:adj:pl:nom:m1:pos</string>
          </f>
         </fs>
        </f>
       </fs>
      </seg>

В этом xml повторяются только узлы (все родительские узлы встречаются только один раз)

Я пытаюсь получить:

        <f name="orth">
         <string>Sami</string>
        </f>

и

          <f name="interpretation">
           <string>sam:adj:pl:nom:m1:pos</string>
          </f>

Нет ни одного случая во всем xml, если бы они отсутствовали.

Это мой код:

    InputStream inputStream = new FileInputStream(file);
    Reader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
    InputSource inputSource = new InputSource(inputStreamReader);
    inputSource.setEncoding("UTF-8");
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    Document document = documentBuilder.parse(inputSource);
    document.getDocumentElement().normalize();
    NodeList nodeListSeg = document.getElementsByTagName("seg");
    for(int i = 0; i < nodeListSeg.getLength(); i++) {
        if(nodeListSeg.item(i).getFirstChild().getFirstChild().getNodeType() == Node.ELEMENT_NODE)
            words.add(((Element) nodeListSeg.item(i).getFirstChild().getFirstChild()).getTextContent().trim());
        if(nodeListSeg.item(i).getLastChild().getNodeType() == Node.ELEMENT_NODE)
            words.add(((Element) nodeListSeg.item(i).getLastChild()).getTextContent().trim());
    }
    inputStreamReader.close();
    inputStream.close();

Еще один подход, который я пробовал, заключался в проверке значений атрибутов:

if(((Element) nodeListSeg.item(i).getFirstChild()).getAttribute("name").equals("orth")) {...}
if(((Element) nodeListSeg.item(i).getFirstChild()).getAttribute("name").equals("interpretation")) 

Но это сравнение никогда не вернется.

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Как обычно, XPath - намного лучшая альтернатива:

    Document doc = DocumentBuilderFactory
            .newInstance()
            .newDocumentBuilder()
            .parse(new File(...));

    XPath xp = XPathFactory
            .newInstance()
            .newXPath();

    String s1 = (String) xp.evaluate("//f[@name='orth']/string/text()", doc, XPathConstants.STRING);
    System.out.println(s1);
    String s2 = (String) xp.evaluate("//f[@name='interpretation']/string/text()", doc, XPathConstants.STRING);
    System.out.println(s2);
0 голосов
/ 05 июня 2019

Решение оказывается таким:

NodeList nodeListSeg = document.getElementsByTagName("seg");
for(int i = 0; i < nodeListSeg.getLength(); i++) {
    NodeList nodeListChildren = nodeListSeg.item(i).getChildNodes();
    for(int j = 0; j < nodeListChildren.getLength(); j++) {
        if(nodeListChildren.item(j).getNodeType() == Node.ELEMENT_NODE) {
            String text = ((Element) nodeListChildren.item(j)).getTextContent().toLowerCase().trim();
            String[] stringArray = text.split(" ");
            System.out.println(stringArray[0] + "\t" + stringArray[stringArray.length - 1]);
        }
    }
}

Таким образом, получается, что все узлы text в узле FS не были проанализированы правильно и все рассматриваются как одинэлемент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...