Проблема - 1: Мне нужно разобрать кучу XML-файлов на Java, которые иногда и недействительно содержат HTML-объекты, такие как
blockquote>—
. XML имеет только пять предопределенных объектов .
—
,не входит в их число. Он работает только при использовании в простом HTML или в устаревшем JSP. Таким образом, SAX не поможет. Это можно сделать, используя
StaX
, который имеет API-интерфейс с высоким уровнем итератора. [Собрано из этой ссылки )Проблема - 2: Я обнаружил, что могу переопределить resolveEntity в org.xml.sax.helpers.DefaultHandler, но как использовать это с API более высокого уровня?
blockquote>Streaming API для XML, называемый StaX, является API для
reading and writing XML Documents
.
StaX
- это Pull-Parsing модель. Приложение может взять на себя управление анализом XML-документов, потянув (принимая) события от анализатора.Ядро StaX API относится к
two categories
, и они перечислены ниже. Они
- API на основе курсора: это
low-level API
. API на основе курсора позволяет приложению обрабатывать XML как поток токенов aka events- API на основе Iterator: API-интерфейс, основанный на итераторе
higher-level
, позволяет приложению обрабатывать XML как ряд объектов событий, каждый из которых связывает фрагмент структуры XML с приложением.
STaX API has support for the notion of not replacing character entity references
, с помощью свойства IS_REPLACING_ENTITY_REFERENCES :Требуется, чтобы синтаксический анализатор заменил ссылки на внутренние сущности ссылкой на их заменяющий текст и отчет их как символы
Это можно установить в
XmlInputFactory
, который затем, в свою очередь, используется для построенияXmlEventReader
илиXmlStreamReader
.Тем не менее, API должен сказать, что это свойство предназначено только для принудительной реализации для замены, вместо того, чтобы заставлять его не замещать их.
Вы можете попробовать. Надеюсь, он решит вашу проблему. Для вашего случая,
Main.java
import java.io.FileInputStream; import java.io.FileNotFoundException; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.EntityReference; import javax.xml.stream.events.XMLEvent; public class Main { public static void main(String[] args) { XMLInputFactory inputFactory = XMLInputFactory.newInstance(); inputFactory.setProperty( XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false); XMLEventReader reader; try { reader = inputFactory .createXMLEventReader(new FileInputStream("F://test.xml")); while (reader.hasNext()) { XMLEvent event = reader.nextEvent(); if (event.isEntityReference()) { EntityReference ref = (EntityReference) event; System.out.println("Entity Reference: " + ref.getName()); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XMLStreamException e) { e.printStackTrace(); } } }
test.xml:
Some text — invalid! Выход:
Ссылка на объект: nbsp
Ссылка на объект: mdash
blockquote>Кредит отправляется на
@skaffman
.Ссылки по теме:
- http://www.journaldev.com/1191/how-to-read-xml-file-in-java-using-java-stax-api
- http://www.journaldev.com/1226/java-stax-cursor-based-api-read-xml-example
- http: // www. vogella.com/tutorials/JavaXML/article.html
- Существует ли Java XML API, который может анализировать документ без разрешения объектов символов?
UPDATE:
Проблема - 3: Есть ли способ использовать StaX для «фильтрации» сущностей (например, заменяя их чем-то другим) и все еще обрабатывать документ в конце процесса?
blockquote>Чтобы создать новый документ с использованием API StAX, необходимо создать
XMLStreamWriter
, который предоставляет методы для создания XML-открывания и закрытия теги, атрибуты и содержание символов.Для документа существует 5 методов
XMLStreamWriter
.
xmlsw.writeStartDocument();
- инициализирует пустой документ, к которому можно добавить элементыxmlsw.writeStartElement(String s)
- создает новый элемент с именем sxmlsw.writeAttribute(String name, String value)
- добавляет имя атрибута с соответствующим значением последнему элементу, создаваемому вызовом writeStartElement. Можно добавлять атрибуты до тех пор, пока не будет выполнен вызов writeElementStart, writeCharacters или writeEndElement.xmlsw.writeEndElement
- закрыть последний начатый элементxmlsw.writeCharacters(String s)
- создает новый текстовый узел с содержимым s в качестве содержимого последнего начатого элемента.Пример с примером прилагается:
StAXExpand.java
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import java.util.Arrays; public class StAXExpand { static XMLStreamWriter xmlsw = null; public static void main(String[] argv) { try { xmlsw = XMLOutputFactory.newInstance() .createXMLStreamWriter(System.out); CompactTokenizer tok = new CompactTokenizer( new FileReader(argv[0])); String rootName = "dummyRoot"; // ignore everything preceding the word before the first "[" while(!tok.nextToken().equals("[")){ rootName=tok.getToken(); } // start creating new document xmlsw.writeStartDocument(); ignorableSpacing(0); xmlsw.writeStartElement(rootName); expand(tok,3); ignorableSpacing(0); xmlsw.writeEndDocument(); xmlsw.flush(); xmlsw.close(); } catch (XMLStreamException e){ System.out.println(e.getMessage()); } catch (IOException ex) { System.out.println("IOException"+ex); ex.printStackTrace(); } } public static void expand(CompactTokenizer tok, int indent) throws IOException,XMLStreamException { tok.skip("["); while(tok.getToken().equals("@")) {// add attributes String attName = tok.nextToken(); tok.nextToken(); xmlsw.writeAttribute(attName,tok.skip("[")); tok.nextToken(); tok.skip("]"); } boolean lastWasElement=true; // for controlling the output of newlines while(!tok.getToken().equals("]")){ // process content String s = tok.getToken().trim(); tok.nextToken(); if(tok.getToken().equals("[")){ if(lastWasElement)ignorableSpacing(indent); xmlsw.writeStartElement(s); expand(tok,indent+3); lastWasElement=true; } else { xmlsw.writeCharacters(s); lastWasElement=false; } } tok.skip("]"); if(lastWasElement)ignorableSpacing(indent-3); xmlsw.writeEndElement(); } private static char[] blanks = "\n".toCharArray(); private static void ignorableSpacing(int nb) throws XMLStreamException { if(nb>blanks.length){// extend the length of space array blanks = new char[nb+1]; blanks[0]='\n'; Arrays.fill(blanks,1,blanks.length,' '); } xmlsw.writeCharacters(blanks, 0, nb+1); } }
CompactTokenizer.java
import java.io.Reader; import java.io.IOException; import java.io.StreamTokenizer; public class CompactTokenizer { private StreamTokenizer st; CompactTokenizer(Reader r){ st = new StreamTokenizer(r); st.resetSyntax(); // remove parsing of numbers... st.wordChars('\u0000','\u00FF'); // everything is part of a word // except the following... st.ordinaryChar('\n'); st.ordinaryChar('['); st.ordinaryChar(']'); st.ordinaryChar('@'); } public String nextToken() throws IOException{ st.nextToken(); while(st.ttype=='\n'|| (st.ttype==StreamTokenizer.TT_WORD && st.sval.trim().length()==0)) st.nextToken(); return getToken(); } public String getToken(){ return (st.ttype == StreamTokenizer.TT_WORD) ? st.sval : (""+(char)st.ttype); } public String skip(String sym) throws IOException { if(getToken().equals(sym)) return nextToken(); else throw new IllegalArgumentException("skip: "+sym+" expected but"+ sym +" found "); } }
Для получения дополнительной информации вы можете ознакомиться с учебником
Вероятно, Вы будете интересоваться Intel VTune . Довольно полезный и позволяет собирать события низкого уровня как неудачные обращения в кэш, который помогает много в настройке.
Gprof, если Вы используете gcc. Это не может быть удобно для пользователя, но все еще полезно.
Не C++ программное обеспечение CodeAnalyst определенного, но AMD является бесплатным и упаковывается функцией.
http://developer.amd.com/cpu/codeanalyst/codeanalystwindows/Pages/default.aspx
Определите количество (часть пакета IBM PurifyPlus / Рациональный пакет PurifyPlus) очень хороший профилировщик, но не точно дешевый. Это доступно на нескольких платформах, также - я использовал его на Солярисе, Windows и Linux.
Зависит от того, что необходимо сделать:
Это не то же.
Для 1, используйте одного из рекомендуемых профилировщиков.
Для 2, профилировщик, которого я очень предпочитаю, является тем, который Вы уже имеете:
http://www.wikihow.com/Optimize-Your-Program%27s-Performance
, Чтобы видеть, как это идет, проверьте это.
Для C++, что касается C# и любого языка, который поощряет слои абстракции, те слои могут или не могут быть хорошими с точки зрения разработки программного обеспечения, но они могут уничтожить производительность. Каждый вызов метода является обходом в осуществлении Вашей программы, и стиль поощряет Вас вкладывать те вещи, иногда напрасно. Также стиль отговаривает Вас знать или заботиться о том, что продолжается в них. Можно найти их созданием и удалением объектов внизу на уровне и уровне общности далеко вне того, в чем действительно нужно приложение.
Можно использовать анализатор thatВґs в Sun Studio 12 на Linux или Солярисе. ItЕ›, свободный. http://developers.sun.com/sunstudio/index.jsp
Если Вы работаете Premium версия VS 2010 затем, Вы получаете профилировщика с ним.
я также использовал несколько других свободных, но они не выдерживают сравнение с на поставках MS. Полезный как второе мнение все же.
Если у Вас есть доступ к Mac, то я рекомендую использовать Акула от инструментов CHUD.