Могу ли я заставить JAXB не преобразовывать «в», например, при сортировке XML?

У меня есть объект, который обрабатывается XML с помощью JAXB. Один элемент содержит строку, которая включает в себя кавычки («). В результате XML имеет« где »существует.

Несмотря на то, что это обычно предпочтительнее, мне нужен мой вывод, чтобы соответствовать устаревшей системе. Как заставить JAXB НЕ преобразовывать объекты HTML?

Спасибо за ответы. Тем не менее, я никогда не вижу вызов обработчика (). Можете ли вы взглянуть и посмотреть, что я делаю неправильно? Благодаря!

 package org.dc.model; import java.io.IOException; import java.io.Writer; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.dc.generated.Shiporder; import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler; public class PleaseWork { public void prettyPlease() throws JAXBException { Shiporder shipOrder = new Shiporder(); shipOrder.setOrderid("Order's ID"); shipOrder.setOrderperson("The woman said, \"How ya doin & stuff?\""); JAXBContext context = JAXBContext.newInstance("org.dc.generated"); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() { @Override public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { out.write("Called escape for characters = " + ch.toString()); } }); marshaller.marshal(shipOrder, System.out); } public static void main(String[] args) throws Exception { new PleaseWork().prettyPlease(); } } 

Вывод:

   The woman said, "How ya doin & stuff?"  

и, как вы можете видеть, обратный вызов никогда не отображается. (Как только я получаю вызов callback, я буду беспокоиться о том, что он действительно делает то, что я хочу.)

Решение моего товарища по команде найдено:

 PrintWriter printWriter = new PrintWriter(new FileWriter(xmlFile)); DataWriter dataWriter = new DataWriter(printWriter, "UTF-8", DumbEscapeHandler.theInstance); marshaller.marshal(request, dataWriter); 

Вместо передачи xmlFile в marshal () передайте DataWriter, который знает как кодировку, так и соответствующий обработчик эвакуации, если таковой имеется.

Примечание. Поскольку DataWriter и DumbEscapeHandler находятся в пакете com.sun.xml.internal.bind.marshaller, вы должны загружать javac.

Я только что сделал свой собственный обработчик как class:

 import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import com.sun.xml.bind.marshaller.CharacterEscapeHandler; public class XmlCharacterHandler implements CharacterEscapeHandler { public void escape(char[] buf, int start, int len, boolean isAttValue, Writer out) throws IOException { StringWriter buffer = new StringWriter(); for (int i = start; i < start + len; i++) { buffer.write(buf[i]); } String st = buffer.toString(); if (!st.contains("CDATA")) { st = buffer.toString().replace("&", "&").replace("<", "<") .replace(">", ">").replace("'", "'") .replace("\"", """); } out.write(st); System.out.println(st); } } 

в методе маршаллера просто позвоните:

 marshaller.setProperty(CharacterEscapeHandler.class.getName(), new XmlCharacterHandler()); 

он отлично работает.

Я немного играл с вашим примером и отлаживал код JAXB. И, похоже, это что-то особенное в кодировке UTF-8. Свойство escapeHandler для MarshallerImpl кажется корректным. Однако он используется не в каждом контексте. Если я искал вызовы MarshallerImpl.createEscapeHandler() я обнаружил:

 public XmlOutput createWriter( OutputStream os, String encoding ) throws JAXBException { // UTF8XmlOutput does buffering on its own, and // otherwise createWriter(Writer) inserts a buffering, // so no point in doing a buffering here. if(encoding.equals("UTF-8")) { Encoded[] table = context.getUTF8NameTable(); final UTF8XmlOutput out; if(isFormattedOutput()) out = new IndentingUTF8XmlOutput(os,indent,table); else { if(c14nSupport) out = new C14nXmlOutput(os,table,context.c14nSupport); else out = new UTF8XmlOutput(os,table); } if(header!=null) out.setHeader(header); return out; } try { return createWriter( new OutputStreamWriter(os,getJavaEncoding(encoding)), encoding ); } catch( UnsupportedEncodingException e ) { throw new MarshalException( Messages.UNSUPPORTED_ENCODING.format(encoding), e ); } } 

Обратите внимание, что в вашей настройке учитывается верхняя секция (...equals("UTF-8")...) . Однако этот человек не принимает escapeHandler . Однако, если вы установите кодировку для любого другого, вызывается нижняя часть этого метода ( createWriter(OutputStream, String) ), и в этом используется escapeHandler , поэтому EH играет свою роль. Итак, добавив …

  marshaller.setProperty(Marshaller.JAXB_ENCODING, "ASCII"); 

вызывает вызов пользовательского CharacterEscapeHandler . Не совсем уверен, но я бы предположил, что это ошибка в JAXB.

@ Elliot вы можете использовать это, чтобы включить маршаллера в функцию characterEscape. Это странно, но оно работает, если вы установите « Unicode » вместо «UTF-8». Добавьте это до или после установки свойства CharacterEscapeHandler.

 marshaller.setProperty(Marshaller.JAXB_ENCODING, "Unicode"); 

Однако не уверен только, только проверив консоль в вашей среде IDE, потому что она должна отображаться в зависимости от кодировки рабочей области. Лучше также проверить это из файла:

 marshaller.marshal(shipOrder, new File("C:\\shipOrder.txt")); 

Я бы сказал, что самый простой способ – переопределить CharacterEscapeHandler :

 marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CharacterEscapeHandler() { @Override public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { out.write(ch, start, length); } }); 

Похоже, это возможно с реализацией Sun JAXB , хотя я сам этого не делал.

Я проверил спецификацию XML. http://www.w3.org/TR/REC-xml/#sec-references говорит, что «хорошо сформированные документы не должны объявлять ни одно из следующих объектов: amp, lt, gt, apos, quot.», поэтому представляется, что парсер XML, используемый устаревшей системой, не соответствует.

(Я знаю, что это не решает вашу проблему, но, по крайней мере, приятно сказать, какой компонент нарушен).

Это работает для меня после прочтения других сообщений:

 javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext.newInstance(object); marshaller = jc.createMarshaller(); marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler()); public static class CustomCharacterEscapeHandler implements CharacterEscapeHandler { /** * Escape characters inside the buffer and send the output to the Writer. * (prevent  to be converted <b> but still ok for a<5.) */ public void escape(char[] buf, int start, int len, boolean isAttValue, Writer out) throws IOException { if (buf != null){ StringBuilder sb = new StringBuilder(); for (int i = start; i < start + len; i++) { char ch = buf[i]; //by adding these, it prevent the problem happened when unmarshalling if (ch == '&') { sb.append("&"); continue; } if (ch == '"' && isAttValue) { sb.append("""); continue; } if (ch == '\'' && isAttValue) { sb.append("'"); continue; } // otherwise print normally sb.append(ch); } //Make corrections of unintended changes String st = sb.toString(); st = st.replace("&quot;", """) .replace("&lt;", "<") .replace("&gt;", ">") .replace("&apos;", "'") .replace("&amp;", "&"); out.write(st); } } } 

Я нашел ту же проблему, я исправил это с помощью xmlWriter в файле xmlWriter, есть один метод isEscapeText () и setEscapeTest, который по умолчанию является true, если вы не хотите преобразовать между

 JAXBContext jaxbContext = JAXBContext.newInstance(your class); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // Create a filter that will remove the xmlns attribute NamespaceFilter outFilter = new NamespaceFilter(null, false); // Do some formatting, this is obviously optional and may effect // performance OutputFormat format = new OutputFormat(); format.setIndent(true); format.setNewlines(true); // Create a new org.dom4j.io.XMLWriter that will serve as the // ContentHandler for our filter. XMLWriter writer = new XMLWriter(new FileOutputStream(file), format); writer.setEscapeText(false); // <----------------- this line // Attach the writer to the filter outFilter.setContentHandler(writer); // marshalling marshaller.marshal(piaDto, outFilter); marshaller.marshal(piaDto, System.out); 

это изменение writer.setEscapeText (false); исправлена ​​моя проблема, надеюсь, что это поможет вам

интересно, но со строками вы можете попробовать

 Marshaller marshaller = jaxbContext.createMarshaller(); StringWriter sw = new StringWriter(); marshaller.marshal(data, sw); sw.toString(); 

по крайней мере для меня это не избежать цитат

Самый простой способ использования Sun Marshaller – предоставить вам собственную реализацию CharacterEscapeEncoder, которая ничего не спасет.

  Marshaller m = jcb.createMarshaller(); m.setProperty( "com.sun.xml.bind.marshaller.CharacterEscapeHandler", new NullCharacterEscapeHandler()); 

С

 public class NullCharacterEscapeHandler implements CharacterEscapeHandler { public NullCharacterEscapeHandler() { super(); } public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer) throws IOException { writer.write( ch, start, length ); } } 

По какой-то причине у меня нет времени, чтобы узнать, это сработало для меня при настройке

 marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); 

В отличие от использования "UTF-8" или "Unicode"

Я предлагаю вам попробовать их, и, как сказал @Javatar , проверьте их сбрасывание в файл, используя:

 marshaller.marshal(shipOrder, new File("")); 

и открывая его с достойным текстовым редактором, как notepad ++

  • Конструктор медленного SoapHttpClientProtocol
  • Как указать атрибуты XML-сериализации для поддержки префиксов пространства имен во время десериализации в .NET?
  • Сделать пользовательский class Serializable в Objective-c / iPhone?
  • Подавлять типы нулевых значений от испускания XmlSerializer
  • {" не ожидалось.} Deserializing Twitter XML
  • XmlSerializer: удалить ненужные пространства имен xsi и xsd
  • Что является лучшей альтернативой Java Serialization?
  • Сериализация XML и унаследованные типы
  • Почему моя публичная собственность не сериализована XmlSerializer?
  • Как декодировать строку в строку XML в C #
  • XSLT: как преобразовать XML-узел в строку
  • Давайте будем гением компьютера.