Pergunta

Eu tenho milhares de documentos SGML, alguns bem formados, outros não tão bem formados. Preciso atingir certos elementos nos documentos, mas toda vez que vou carregar e tento lê -los em um Xdocument, Xmldocument ou mesmo apenas um fluxo de streaming, recebo diferentes erros de Xmlexception.

Coisas como "'[' são um token inesperado.". Por quê? Porque eu tenho um documento com doctype como

<!DOCTYPE RChapter PUBLIC "-//LSC//DTD R Chapter for Authoring//EN" [] >

E eu aprendi que o [] precisa ter algo válido por dentro. Novamente, não controlo a criação dos documentos, mas tenho que "quebrá -los" e obter os dados que quero. Outro exemplo é ter um elemento "não fechado", por exemplo:

<Caption>Plants, and facilities<hardhyphen><hyphen>Inspection.</Caption>

Essa xmlexception é "a tag" hífen "na linha 27 não corresponde à etiqueta final da 'Legenda'. Linha 27, posição 58". Óbvio, certo?

Mas então a pergunta é como você pode realmente obter certos elementos nesses documentos, sem encontrar o XmlexCepções. Um analisador sax é o caminho certo? Eu basicamente quero abrir o documento, ir direto ao elemento que quero (sem me preocupar com o que pode ou não estar bem formado por perto), puxe os dados e siga em frente. Devo apenas esquecer a análise com xmldocument, xdocument e apenas fazer substituições simples de cordas como

str.Replace("<hardhypen><hyphen>", "-")

e então tente carregá -lo em um dos analisadores XML. Alguma dica sobre estratégias?

Foi útil?

Solução

A questão é que você está tentando analisar o SGML com uma ferramenta XML. Eles não são iguais. Se você deseja usar uma ferramenta/idioma XML para acessar os dados, provavelmente precisará converter o SGML em XML antes de tentar analisá -los.

Idealmente, você usaria uma linguagem/ferramenta que suporta SGML (como Omnimark) ou algo que pode lidar com dados "XML como" (como Nokogiri da primeira resposta?).

Isso pode ser bastante direto, mas pode ficar complicado em alguns pontos. Especialmente se você está falando de vários doces (DTDs). (Além disso, não existe sgml. tem ter um dtd.)

Aqui estão algumas diferenças entre o SGML e o XML que você precisa lidar. (Você pode não querer seguir esse caminho, mas pode ser útil para fins informativos de qualquer maneira.):

  1. Declaração Doctype

    A declaração Doctype em seu exemplo é uma SGML DOCTYPE perfeitamente válida. o [] (subconjunto interno) não precisa ter nada nele. Se você tiver declarações no subconjunto interno (geralmente declarações de entidade), provavelmente terá que manter uma declaração Doctype no XML.

    O problema que o analisador XML está tendo é que você não tem um identificador de sistema na declaração. Em uma declaração XML Doctype, o identificador do sistema é necessário se houver um identificador público. Em uma declaração SGML Doctype, não é necessária.

    Resumindo: A menos que você precise do XML para analisar um DTD/esquema ou tenha declarações no subconjunto interno, retire a declaração Doctype. Se o XML precisar ser válido, você precisará adicionar um identificador de sistema. Não se esqueça de adicionar o <?xml ...?> instrução de processamento.

  2. Elementos sem tags finais

    o <hardhyphen> e <hyphen> Os elementos são SGML válidos. O SGML DTD permite que você especifique a minimização de tags. O que isso significa é que você pode especificar se é necessária ou não uma etiqueta final. (Você também pode tornar a tag de início opcional, mas isso é uma conversa louca.) No XML, você precisa fechar esses elementos (como <hardhyphen/> ou <hardhyphen></hardhyphen>)

    A melhor coisa a fazer é olhar para o seu SGML DTD e ver quais elementos têm tags finais opcionais. A minimização da tag é especificada logo após o nome do elemento na declaração do elemento. A '-' significa que a tag é necessária. E 'O' (letra 'oh') significa que a tag é opcional. Por exemplo, se você vir <!ELEMENT hyphen - o (#PCDATA)>, isso significa que a etiqueta inicial é necessária (-) e a etiqueta final é opcional (o). Se você ver <!ELEMENT hyphen - - (#PCDATA)>, tanto o início quanto as tags finais são necessárias.

    Resumindo: fechar adequadamente todos os elementos que não têm tags finais

  3. Instruções de processamento

    Instruções de processamento (PIs) no SGML não têm o segundo ? Quando eles estão fechados como o XML. Você precisará adicionar o segundo ?.

    Exemplo sgml pi: <?asdf jkl>

    Exemplo XML pi: <?asdf jkl?>

  4. Inclusões/exclusões

    Você provavelmente não precisará se preocupar com isso, mas em um DTD SGML, você pode especificar em uma declaração de elemento de que outro elemento é permitido em qualquer lugar dentro desse elemento (ou não é permitido). Isso pode ser uma dor se o seu XML alvo precisar analisar um DTD; O XML DTD's não permite inclusões/exclusões.

    É assim que uma inclusão pode parecer:

    <!ELEMENT chapter - - (section)+ +(revst|revend)>

    Isso está dizendo que revst ou revend são permitidos em qualquer lugar dentro de chapter. Se a declaração do elemento tivesse -(revst|revend), isso significaria que revst ou revend é não permitido em qualquer lugar dentro de chapter.

Espero que isto ajude.

Outras dicas

Sim, use Nokogiri.

Role um pouco para baixo nessa página e copie o código em "Sinopse" em um arquivo, digamos xml-parser.rb. Então, se você está em um Mac (Ruby já vem instalado em Macs.), No terminal, execute gem install nokogiri, e depois execute o arquivo com: ruby xml-parser.rb.

Você também pode digitar irb diretamente do terminal e depois require 'nokogiri' E comece a brincar com a API Nokogiri em tempo real. Tenho que amar o rubi interativo. :)

Se você estiver no Windows, tente isto Instalador Ruby para Windows.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top