Pergunta

Tudo bem, então aqui está o meu problema. Preciso gerar XML em Java para passar para outro aplicativo. Comecei a pensar que isso seria fácil usando um org.w3c.dom.document. Infelizmente, o aplicativo que eu preciso passar o XML exige que caracteres especiais como "precisam ser codificados como ASCII (") em vez de sua entidade de personagem ("). Alguém conhece uma solução simples para isso?

PS Alterar o aplicativo de destino não é uma opção.

ATUALIZAÇÃO: Então, digamos que meu aplicativo receba a seguinte string como entrada:

he will "x" this if needed

Meu aplicativo precisa produzir isso:

<field value="he will &#034;x&#034; this if needed"/>

O gerador XML que estou usando e acho que a maioria dos outros produz isso, mas isso não é válido para o meu alvo:

<field value="he will &quot;x&quot; this if needed"/>

Sei que meu alvo pode não estar de acordo com os padrões XML, mas isso não me ajuda, pois não tenho controle sobre isso. Esta é a minha situação e tenho que lidar com isso. Alguma idéia além de simplesmente converter todos os personagens especiais à mão?

Foi útil?

Solução

Eu me pergunto como você serializa o XML-a uma string, um fluxo, etc. Você pode pós-processo de sua saída para substituir as referências de entidade geral por seus equivalentes numéricos, por exemplo,

sed 's/&lt;/\&#60;/g; s/&gt;/\&#62;/g; s/&amp;/\&#38;/g; s/&apos;/\&#39/g; s/&quot;/\&#34;/g'

ou

xmlResultString.replaceAll("&lt;", "&#60;"); //etc. for other entities

Existem exatamente 5 entidades gerais predefinidas em XML (http://www.w3.org/tr/rec-xml/#sec-predefined-ent) e você pode executar com segurança isso como uma substituição textual. Não há perigo que ele modifique qualquer coisa, exceto as referências (bem, talvez em comentários e pis, mas não parece que seu cenário as use ou que o alvo os aceite).

Concordo com Mark que seu aplicativo de destino não é um processador XML em conformidade. Pelo menos vem com documentação que afirma explicitamente onde diverge do XML. Acredito que a recomendação (link acima) discorde do comentário de Christopher, embora seja irrelevante à pergunta de OP, pois seu alvo declara sua não conformidade à recomendação.

Ari.

Outras dicas

Que eu saiba, a API padrão não expõe o mecanismo de escape. Você provavelmente precisaria escrever seu próprio emissor XML.

Se você não se importa com uma API de terceiros, você pode usar JDOM. Algo como:

XMLOutputter outputter = new XMLOutputter() {
  @Override
  public String escapeAttributeEntities(String sequence) {
    // TODO: bug: code only works for Basic Multilingual Plane
    StringBuilder out = new StringBuilder();
    for (int i = 0; i < sequence.length(); i++) {
      process(sequence.charAt(i), out);
    }
    return out.toString();
  }

  private void process(char codePoint, StringBuilder out) {
    if (codePoint == '"' || codePoint == '\'' || codePoint == '&'
        || codePoint == '<' || codePoint == '>' || codePoint > 127) {
      out.append("&#");
      out.append(Integer.toString(codePoint));
      out.append(";");
    } else {
      out.append(codePoint);
    }
  }
};
outputter.setFormat(Format.getPrettyFormat().setEncoding("US-ASCII"));

Element foo = new Element("foo").setAttribute("msg",
    "he will \"x\" this if needed");
Document doc = new Document().setRootElement(foo);
outputter.output(doc, System.out);

Isso emite:

<?xml version="1.0" encoding="US-ASCII"?>
<foo msg="he will &#34;x&#34; this if needed" />

(Eu ainda daria o XML Spec uma vez antes de fazer isso e consertar o manuseio de personagens para apoiar os personagens acima de u+ffff.)

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