2011-02-01 17 views
19

Estoy buscando un analizador en Java que pueda analizar un documento formateado en SGML.Analizador SGML en Java?

Para monitores duplicados: estoy al tanto de los otros dos hilos que discuten este tema: Parsing Java String with SGML Java SGML to XML conversion? Pero ninguno de ellos tiene una resolución, por lo tanto el nuevo tema.

Para las personas que confunden XML con SGML: Por favor, lea esto: http://www.w3.org/TR/NOTE-sgml-xml-971215#null (en pocas palabras, hay suficientes diferencias sutiles en al menos hacerlo inservible en su forma de vainilla)

Para las personas que gustan de pedir carteles para Google: Ya lo hice y lo más cercano que pude llegar fue el popularmente popular SAXParser: http://download.oracle.com/javase/1.4.2/docs/api/javax/xml/parsers/SAXParser.html Pero eso, por supuesto, debe ser un analizador XML. Estoy mirando para ver si alguien ha implementado una modificación del analizador SAX para acomodar SGML.

Por último, no puedo usar SX porque estoy buscando una solución Java.

Gracias! :)

+1

personas siguen utilizando SGML? Tengo curiosidad genuina, ¿para qué se usa en tu caso? – skaffman

+0

Tengo alrededor de 2500 documentos formateados en SGML. Necesito usar los datos para algunos análisis estadísticos. Estoy recopilando un programa rápido para determinar la distribución de las etiquetas, revisé algunas de ellas y solo parecen utilizar algunas etiquetas. En ese caso, podría usar fácilmente el SAXParser. – user183037

+0

Tengo decenas de miles de archivos SGML, y más se hacen todo el tiempo. ¡SGML todavía se usa ampliamente en la industria editorial, sin embargo, sin complicaciones! – Woody

Respuesta

4

tengo unas pocas aproximaciones a este problema

La primera es lo que hizo - comprobar para ver si el documento SGML es lo suficientemente cerca de XML para el analizador SAX estándar para trabajar.

El segundo es hacer lo mismo con los analizadores HTML. El truco aquí es encontrar uno que no ignore elementos que no sean HTML.

Encontré algunos analizadores de Java SGML, más en acedemia, al buscar "sgml parser Java". No sé qué tan bien funcionan.

El último paso es tomar un analizador SGML estándar (que no sea Java) y transformar los documentos en algo que pueda leer en Java.

Parece que pudiste trabajar con el primer paso.

+1

No encontré ningún recurso para un analizador Java SGML en absoluto; sería genial si pudiera publicar el enlace si lo encuentra de nuevo, ¡gracias! – user183037

+0

De hecho, cuando volví a mirar, no pude encontrar nada tampoco. –

+0

:) ¡Está bien, gracias por intentarlo! – user183037

1

No hay una API para analizar SGML utilizando Java en este momento. Tampoco hay ninguna API o biblioteca para convertir SGML a XML y luego analizarlo usando Java. Con el estado de SGML reemplazado por XML para todos los proyectos en los que he trabajado hasta ahora, no creo que se haya hecho ningún trabajo en esta área, pero eso es solo una suposición.

Here es un código de código fuente abierto de una Universidad que lo hace, sin embargo no lo he intentado y tendrías que buscar para encontrar las otras clases dependientes. Creo que la única solución viable en Java requeriría expresiones regulares.

Además, aquí hay un link para el software público SGML/XML.

1

Java SE incluye un analizador de HTML en el paquete javax.swing.text.html.parser. Reclama en su documentación ser un analizador SGML general, pero luego contrademan en la documentación que solo debe usarlo con la clase HTML DTD proporcionada.

Si lo pone en modo indulgente y sus documentos SGML no tienen muchas etiquetas finales implícitas, puede obtener resultados razonables.

Lea sobre el analizador en su JavaDoc, aquí: http://docs.oracle.com/javase/6/docs/api/javax/swing/text/html/parser/DocumentParser.html

Crear una instancia como esta:

new DocumentParser(DTD.getDTD("html32")) 

o usted podría ignorar las advertencias contra el uso de un DTD personalizado con DocumentParser, y crear una subclase de DTD que coincida con las reglas de su propio formato SGML.

Esto claramente no es un analizador SGML de fuerza industrial, pero debería ser un buen punto de partida para un esfuerzo de migración de datos de una sola vez. Lo encontré útil en proyectos anteriores para analizar HTML.

1

Uso OpenSP a través de JNI, ya que parece que no hay un analizador de Java SGML puro. He escrito un envoltorio experimental tipo SAX que está disponible en http://sourceforge.net/projects/sasgml (por supuesto, tiene todos los inconvenientes de JNI ... pero fue suficiente para mis requisitos).

Otro enfoque es convertir el documento a XML utilizando sx desde Open SP, y luego ejecutar un analizador SAX tradicional.

0

Aunque es una publicación muy antigua y no estoy afirmando que la respuesta que proporciono sea perfecta, pero sirvió para mi propósito. Así que estoy manteniendo este código que escribí utilizando stack para obtener los datos de una manera que era necesaria en mi caso. Espero que pueda ser útil para otros.

try (BufferedReader br = new BufferedReader(new FileReader(new File(
       fileName)))) { 
      while ((line = br.readLine()) != null) { 
       line = line.trim(); 
       int startOfTag = line.indexOf("<"); 
       int endOfTag = line.indexOf(">"); 
       String currentTag = ""; 

       if (startOfTag > -1 && endOfTag > -1) { 
        if (countStart) 
         headerTagsCounter++; 
        currentTag = line.substring(startOfTag + 1, endOfTag); 
        String currentData = line.substring(endOfTag + 1, 
          line.length()); 
        if (i == 1) { 
         tagStack.push(currentTag); 
         i++; 
        } 
        if (currentData.isEmpty() || currentData == "") {//If there is no data, its a parent tag... 
         if (!currentTag.contains("/")) {// if its an opening tag... 
          switch (currentTag) {// these tags are useless in my case, so just skipping these tags. 
          case "CORRECTION": 
          case "PAPER": 
          case "PRIVATE-TO-PUBLIC": 
          case "DELETION": 
          case "CONFIRMING-COPY": 
          case "CAPTION": 
          case "STUB": 
          case "COLUMN": 
          case "TABLE-FOOTNOTES-SECTION": 
          case "FOOTNOTES": 
          case "PAGE": 
           break; 
          default: { 
           countStart = false; 
           int tagCounterNumber = 0; 
           String historyTagToRemove = ""; 
           for (String historyTag : historyStack) { 
            String tagCounter = ""; 
            if (historyTag.contains(currentTag)) {//if it's a repeating tag..Append the counter and update the same in history tag.. 
             historyTagToRemove = historyTag; 
             if (historyTag 
               .equalsIgnoreCase(currentTag)) { 
              tagCounterNumber = 1; 
             } else if (historyTag.length() > currentTag 
               .length()) { 
              tagCounter = historyTag 
                .substring(currentTag 
                  .length()); 
              if (tagCounter != null 
                && !tagCounter.isEmpty()) { 
               tagCounterNumber = Integer 
                 .parseInt(tagCounter) + 1; 
              } 
             } 
            } 
           } 
           if (tagCounterNumber > 0) 
            currentTag += tagCounterNumber; 
           if (historyTagToRemove != null 
             && !historyTagToRemove.isEmpty()) { 
            historyStack.remove(historyTagToRemove); 
            historyStack.push(currentTag); 
           } 
           tagStack.push(currentTag); 
           break; 
          } 
          } 
         } else// if its end of a tag... Match the current tag with top of stack and if its a match, pop it out 
         { 
          currentTag = currentTag.substring(1); 
          String tagRemoved = ""; 
          String topStackTag = tagStack.lastElement(); 
          if (topStackTag.contains(currentTag)) { 
           tagRemoved = tagStack.pop(); 
           historyStack.push(tagRemoved); 
          } 
          if (tagStack.size() < 2) 
           cik = ""; 
          if (tagStack.size() == 2 && cik != null 
            && !cik.isEmpty()) 
           for (int j = headerTagsCounter - 1; j < tagList.size(); j++) { 
            String item = tagList.get(j); 
            if (!item.contains("@@")) { 
             item += "@@" + cik; 
             tagList.remove(j); 
             tagList.add(j, item); 
            } 
           } 
         } 
        } else {// if current tag has some data... 
         currentData = currentData.trim(); 
         String stackValue = ""; 
         for (String tag : tagStack) { 
          if (stackValue != null && !stackValue.isEmpty() 
            && stackValue != "") 
           stackValue = stackValue + "||" + tag; 
          else 
           stackValue = tag; 
         } 
         switch (currentTag) { 
         case "ACCESSION-NUMBER": 
          accessionNumber = currentData; 
          break; 
         case "FILING-DATE": 
          dateFiled = currentData; 
          break; 
         case "TYPE": 
          formType = currentData; 
          break; 
         case "CIK": 
          cik = currentData; 
          break; 
         } 
         tagList.add(stackValue + "$$" + currentTag + "::"+ currentData); 
        } 
       } 
      } 
// Now all your data is available with in tagList, stack is separated by ||, key is separated by $$ and value is separated by :: 
      } 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
     } 

    } 

Salida:

Fuente de archivo: http://10k-staging.s3.amazonaws.com/edgar0105/2016/12/20/935015/000119312516799070/0001193125-16-799070.hdr.sgml

salida de código:

SEC-HEADER$$SEC-HEADER::0001193125-16-799070.hdr.sgml : 20161220 
SEC-HEADER$$ACCEPTANCE-DATETIME::20161220172458 
SEC-HEADER$$ACCESSION-NUMBER::0001193125-16-799070 
SEC-HEADER$$TYPE::485APOS 
SEC-HEADER$$PUBLIC-DOCUMENT-COUNT::9 
SEC-HEADER$$FILING-DATE::20161220 
SEC-HEADER$$DATE-OF-FILING-DATE-CHANGE::20161220 
SEC-HEADER||FILER||COMPANY-DATA$$CONFORMED-NAME::ARTISAN PARTNERS FUNDS [email protected]@0000935015 
SEC-HEADER||FILER||COMPANY-DATA$$CIK::[email protected]@0000935015 
SEC-HEADER||FILER||COMPANY-DATA$$IRS-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER||COMPANY-DATA$$STATE-OF-INCORPORATION::[email protected]@0000935015 
SEC-HEADER||FILER||COMPANY-DATA$$FISCAL-YEAR-END::[email protected]@0000935015 
SEC-HEADER||FILER||FILING-VALUES$$FORM-TYPE::[email protected]@0000935015 
SEC-HEADER||FILER||FILING-VALUES$$ACT::[email protected]@0000935015 
SEC-HEADER||FILER||FILING-VALUES$$FILE-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER||FILING-VALUES$$FILM-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER||BUSINESS-ADDRESS$$STREET1::875 EAST WISCONSIN AVE STE [email protected]@0000935015 
SEC-HEADER||FILER||BUSINESS-ADDRESS$$CITY::[email protected]@0000935015 
SEC-HEADER||FILER||BUSINESS-ADDRESS$$STATE::[email protected]@0000935015 
SEC-HEADER||FILER||BUSINESS-ADDRESS$$ZIP::[email protected]@0000935015 
SEC-HEADER||FILER||BUSINESS-ADDRESS$$PHONE::[email protected]@0000935015 
SEC-HEADER||FILER||MAIL-ADDRESS$$STREET1::875 EAST WISCONSIN AVE STE [email protected]@0000935015 
SEC-HEADER||FILER||MAIL-ADDRESS$$CITY::[email protected]@0000935015 
SEC-HEADER||FILER||MAIL-ADDRESS$$STATE::[email protected]@0000935015 
SEC-HEADER||FILER||MAIL-ADDRESS$$ZIP::[email protected]@0000935015 
SEC-HEADER||FILER||FORMER-COMPANY$$FORMER-CONFORMED-NAME::ARTISAN FUNDS [email protected]@0000935015 
SEC-HEADER||FILER||FORMER-COMPANY$$DATE-CHANGED::[email protected]@0000935015 
SEC-HEADER||FILER||FORMER-COMPANY1$$FORMER-CONFORMED-NAME::ZIEGLER FUNDS [email protected]@0000935015 
SEC-HEADER||FILER||FORMER-COMPANY1$$DATE-CHANGED::[email protected]@0000935015 
SEC-HEADER||FILER1||COMPANY-DATA1$$CONFORMED-NAME::ARTISAN PARTNERS FUNDS [email protected]@0000935015 
SEC-HEADER||FILER1||COMPANY-DATA1$$CIK::[email protected]@0000935015 
SEC-HEADER||FILER1||COMPANY-DATA1$$IRS-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER1||COMPANY-DATA1$$STATE-OF-INCORPORATION::[email protected]@0000935015 
SEC-HEADER||FILER1||COMPANY-DATA1$$FISCAL-YEAR-END::[email protected]@0000935015 
SEC-HEADER||FILER1||FILING-VALUES1$$FORM-TYPE::[email protected]@0000935015 
SEC-HEADER||FILER1||FILING-VALUES1$$ACT::[email protected]@0000935015 
SEC-HEADER||FILER1||FILING-VALUES1$$FILE-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER1||FILING-VALUES1$$FILM-NUMBER::[email protected]@0000935015 
SEC-HEADER||FILER1||BUSINESS-ADDRESS1$$STREET1::875 EAST WISCONSIN AVE STE [email protected]@0000935015 
SEC-HEADER||FILER1||BUSINESS-ADDRESS1$$CITY::[email protected]@0000935015 
SEC-HEADER||FILER1||BUSINESS-ADDRESS1$$STATE::[email protected]@0000935015 
SEC-HEADER||FILER1||BUSINESS-ADDRESS1$$ZIP::[email protected]@0000935015 
SEC-HEADER||FILER1||BUSINESS-ADDRESS1$$PHONE::[email protected]@0000935015 
SEC-HEADER||FILER1||MAIL-ADDRESS1$$STREET1::875 EAST WISCONSIN AVE STE [email protected]@0000935015 
SEC-HEADER||FILER1||MAIL-ADDRESS1$$CITY::[email protected]@0000935015 
SEC-HEADER||FILER1||MAIL-ADDRESS1$$STATE::[email protected]@0000935015 
SEC-HEADER||FILER1||MAIL-ADDRESS1$$ZIP::[email protected]@0000935015 
SEC-HEADER||FILER1||FORMER-COMPANY2$$FORMER-CONFORMED-NAME::ARTISAN FUNDS [email protected]@0000935015 
SEC-HEADER||FILER1||FORMER-COMPANY2$$DATE-CHANGED::[email protected]@0000935015 
SEC-HEADER||FILER1||FORMER-COMPANY3$$FORMER-CONFORMED-NAME::ZIEGLER FUNDS [email protected]@0000935015 
SEC-HEADER||FILER1||FORMER-COMPANY3$$DATE-CHANGED::[email protected]@0000935015 
SEC-HEADER||SERIES-AND-CLASSES-CONTRACTS-DATA||NEW-SERIES-AND-CLASSES-CONTRACTS$$OWNER-CIK::0000935015 
SEC-HEADER||SERIES-AND-CLASSES-CONTRACTS-DATA||NEW-SERIES-AND-CLASSES-CONTRACTS||NEW-SERIES$$SERIES-ID::S000056665 
SEC-HEADER||SERIES-AND-CLASSES-CONTRACTS-DATA||NEW-SERIES-AND-CLASSES-CONTRACTS||NEW-SERIES$$SERIES-NAME::Artisan Thematic Fund 
SEC-HEADER||SERIES-AND-CLASSES-CONTRACTS-DATA||NEW-SERIES-AND-CLASSES-CONTRACTS||NEW-SERIES||CLASS-CONTRACT$$CLASS-CONTRACT-ID::C000179292 
SEC-HEADER||SERIES-AND-CLASSES-CONTRACTS-DATA||NEW-SERIES-AND-CLASSES-CONTRACTS||NEW-SERIES||CLASS-CONTRACT$$CLASS-CONTRACT-NAME::Investor Shares