Как игнорировать данные, содержащиеся в XML комментариях с использованием JAXP SAX Parser? - PullRequest
1 голос
/ 18 марта 2020

У меня есть большой XML файл, содержащий много пар ключ-значение. Файл содержит как многострочные комментарии, так и фактические данные. В разделе комментариев есть примеры того, как должны быть расположены пары данных / ключ-значение. Парсер SAX, который я сделал, успешно извлекает ключи и значения из файла, но он также считывает примеры ключей / значений, содержащихся в комментариях, чего я не хочу, чтобы это происходило. Как я могу сделать так, чтобы мой SAX-парсер игнорировал все в разделе комментариев? Мне не разрешено редактировать файл, и я должен использовать java.

Ниже приведен пример файла, с которым я работаю. Обратите внимание на наличие тегов данных в разделе комментариев. Я не хочу читать примеры данных в этих тегах, но мой анализатор все равно их записывает.

<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
      Microsoft ResX Schema

      Version 2.0

      The primary goals of this format is to allow a simple XML format
      that is mostly human readable. The generation and parsing of the
      various data types are done through the TypeConverter classes
      associated with the data types.

      Example:

      ... ado.net/XML headers & schema ...
      <resheader name="resmimetype">text/microsoft-resx</resheader>
      <resheader name="version">2.0</resheader>
      <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
      <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
      <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
      <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> **I DO NOT WANT TO READ THIS**
      <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
          <value>[base64 mime encoded serialized .NET Framework object]</value>
      </data>
      <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
          <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
          <comment>This is a comment</comment>
      </data>
-->
    <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    </resheader>

    <data name="AmountUnits" xml:space="preserve">
        <value>Amount/Units</value>
    </data>
</root>

Вот код, который я использую:

public class xmlPropertiesBuilder extends DefaultHandler {
    private boolean valueFound;

    public void readXMLFile(File xmlFile) throws SAXException, IOException, ParserConfigurationException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        parser.parse(xmlFile, this);
        valueFound = false;
    }

    @Override
    public void startDocument() throws SAXException {
        System.out.println("Start Document");
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("End Document");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equals("data")){
            System.out.println("Start Element: " + qName);
            System.out.println("Key: " + attributes.getValue("name"));
        } else if(qName.equals("value")){
            valueFound = true;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equals("data")){
            System.out.println("End Element: " + qName + "\n");
        }

    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(valueFound){
            System.out.println("Value: " + new String(ch, start, length));
            valueFound = false;
        }
    }
}

1 Ответ

0 голосов
/ 18 марта 2020

Похоже, парсер JAXP SAX на самом деле игнорирует данные, содержащиеся в комментариях. Я просто неправильно интерпретировал свои тесты. В моем примере файла XML я не включил некоторые теги, один из которых называется <reshader>. Эти теги повторных шейдеров также содержат тег <value>, который собирал мой синтаксический анализатор (который, как я предполагал, был из комментариев, но оказалось, что он был из повторных шейдеров).

Мне удалось решить мою проблему добавив логическую переменную dataFound, которая будет установлена ​​в true только тогда, когда найден тег. Затем в методе символов я просто изменил условие if с if(valueFound){...} на if(dataFound && valueFound){...}. Наконец, в методе endElement() я устанавливаю для переменной 'dataFound' значение false при обнаружении тега </data>.

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