Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.
Позиция вашего DOM-зависимого скрипта может оказать глубокое влияние на его поведение. Браузеры анализируют HTML-документы сверху донизу. Элементы добавляются в DOM, и сценарии выполняются (как правило), когда они встречаются. Это означает, что порядок имеет значение. Как правило, скрипты не могут найти элементы, которые появляются позже в разметке, потому что эти элементы еще не добавлены в DOM.
Рассмотрим следующую разметку; сценарий # 1 не находит Итак, что вы должны делать? У вас есть несколько вариантов: Переместите свой скрипт дальше по странице, перед закрывающим тегом тела. Организованный таким образом остальная часть документа анализируется до того, как будет выполнен ваш скрипт: Примечание: размещение скриптов внизу как правило, считается лучшей практикой . Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя Примечание. Вы можете просто привязать к Делегированные события имеют преимущество в том, что они могут обрабатывать события из элементов-потомков, которые будут добавлены в документ позже. Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код. jQuery Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к Используйте атрибут [ Для справки, вот код из этого внешнего скрипта : Примечание: атрибут
Вариант 1: Переместите свой скрипт
Вариант 2: jQuery's
ready()
ready()
:
DOMContentLoaded
или window.onload
, но у каждого есть свои оговорки. jQuery ready()
предоставляет гибридное решение. Вариант 3: Делегирование событий
on()
выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:
document
(для демонстрационных целей), вы должны выбрать ближайшего надежного предка. Вариант 4: Атрибут
defer
defer
в .
defer
, логический атрибут] установлен для указания на браузера, который должен выполняться после того, как документ был проанализирован.
document.getElementById("test").addEventListener("click", function(e){
console.log("clicked: %o", this);
});
defer
, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer
может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src
. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10
Возможно, это могло бы помочь: JSefa
можно прочитать файл CSV с этим инструментом и сериализировать его к XML.
Для Части CSV можно использовать моя небольшая библиотека с открытым исходным кодом
Это может быть слишком основным или ограниченным из решения, но разве Вы не могли сделать String.split()
на каждой строке файла, помня массив результата первой строки, чтобы генерировать XML, и просто выложить данные массива каждой строки с надлежащими элементами XML, дополняющими каждое повторение цикла?
Насколько я знаю, нет никакой готовой библиотеки, чтобы сделать, это для Вас, но создания инструмента, способного к переводу от CSV до XML, должно только потребовать, чтобы Вы описали сырой синтаксический анализатор CSV и сцепили JDOM (или Ваша предпочтительная библиотека XML Java) с некоторым кодом связующего звена.
Нет ничего, что я знаю этого, может сделать это без Вас, по крайней мере, пишущий определенный код... Вам будут нужны 2 отдельных библиотеки:
синтаксический анализатор CSV я рекомендовал бы (если Вы не хотите повеселиться для записи собственный Синтаксический анализатор CSV) OpenCSV (Проект SourceForge для парсинга Данных CSV)
, Платформа Сериализации XML должна быть чем-то, что может масштабироваться в случае, если Вы хотите преобразовать большой (или огромный) файл CSV к XML: Моя рекомендация является Java Sun, Передающим Платформу Синтаксического анализатора XML потоком (См. здесь ), который позволяет парсинг получения по запросу И сериализацию.
Вы могли использовать XSLT. Google это и Вы найдет несколько примеров, например, CSV к XML, Если Вы будете использовать XSLT, можно тогда преобразовать XML в любой формат, который Вы хотите.
Существует также хорошая библиотека ServingXML Daniel Parker, который в состоянии преобразовать почти любой формат обычного текста в XML и назад.
пример для Вашего случая может быть найден здесь : Это использует заголовок поля в файле CSV как имя элемента XML.
Я не понимаю, почему Вы хотели бы сделать это. Это почти походит на грузовое культовое кодирование.
Преобразование файла CSV к XML не добавляет значения. Ваша программа уже читает файл CSV, таким образом утверждая необходимость в XML, не работает.
, С другой стороны, читая файл CSV, делая что-то со значениями, и затем сериализируя к XML действительно имеет смысл (хорошо, так же, как использующий XML может иметь смысл...;)), но у Вас, предположительно, уже было бы средство сериализации к XML.
Для этого решения не нужны никакие библиотеки CSV или XML и, я знаю, оно не обрабатывает запрещенных символов и кодирующих проблем, но Вы могли бы интересоваться им также, если Ваш вход CSV не нарушает вышеупомянутые правила.
Внимание: Вы не должны использовать этот код, если Вы не знаете то, что Вы делаете или не имеете шанса пользоваться дальнейшей библиотекой (возможный в некоторых бюрократических проектах)... Используйте StringBuffer для более старых Сред выполнения...
, Таким образом, здесь мы идем:
BufferedReader reader = new BufferedReader(new InputStreamReader(
Csv2Xml.class.getResourceAsStream("test.csv")));
StringBuilder xml = new StringBuilder();
String lineBreak = System.getProperty("line.separator");
String line = null;
List<String> headers = new ArrayList<String>();
boolean isHeader = true;
int count = 0;
int entryCount = 1;
xml.append("<root>");
xml.append(lineBreak);
while ((line = reader.readLine()) != null) {
StringTokenizer tokenizer = new StringTokenizer(line, ",");
if (isHeader) {
isHeader = false;
while (tokenizer.hasMoreTokens()) {
headers.add(tokenizer.nextToken());
}
} else {
count = 0;
xml.append("\t<entry id=\"");
xml.append(entryCount);
xml.append("\">");
xml.append(lineBreak);
while (tokenizer.hasMoreTokens()) {
xml.append("\t\t<");
xml.append(headers.get(count));
xml.append(">");
xml.append(tokenizer.nextToken());
xml.append("</");
xml.append(headers.get(count));
xml.append(">");
xml.append(lineBreak);
count++;
}
xml.append("\t</entry>");
xml.append(lineBreak);
entryCount++;
}
}
xml.append("</root>");
System.out.println(xml.toString());
вход test.csv (украденный от другого ответа на этой странице):
string,float1,float2,integer
hello world,1.0,3.3,4
goodbye world,1e9,-3.3,45
hello again,-1,23.33,456
hello world 3,1.40,34.83,4999
hello 2 world,9981.05,43.33,444
получающийся вывод:
<root>
<entry id="1">
<string>hello world</string>
<float1>1.0</float1>
<float2>3.3</float2>
<integer>4</integer>
</entry>
<entry id="2">
<string>goodbye world</string>
<float1>1e9</float1>
<float2>-3.3</float2>
<integer>45</integer>
</entry>
<entry id="3">
<string>hello again</string>
<float1>-1</float1>
<float2>23.33</float2>
<integer>456</integer>
</entry>
<entry id="4">
<string>hello world 3</string>
<float1>1.40</float1>
<float2>34.83</float2>
<integer>4999</integer>
</entry>
<entry id="5">
<string>hello 2 world</string>
<float1>9981.05</float1>
<float2>43.33</float2>
<integer>444</integer>
</entry>
</root>
У меня есть платформа с открытым исходным кодом для работы с файлами CSV и плоскими файлами в целом. Возможно, это стоит посмотреть: JFileHelpers.
С тем инструментарием можно записать код с помощью бобов, как:
@FixedLengthRecord()
public class Customer {
@FieldFixedLength(4)
public Integer custId;
@FieldAlign(alignMode=AlignMode.Right)
@FieldFixedLength(20)
public String name;
@FieldFixedLength(3)
public Integer rating;
@FieldTrim(trimMode=TrimMode.Right)
@FieldFixedLength(10)
@FieldConverter(converter = ConverterKind.Date,
format = "dd-MM-yyyy")
public Date addedDate;
@FieldFixedLength(3)
@FieldOptional
public String stockSimbol;
}
и затем просто анализируют Ваше использование текстовых файлов:
FileHelperEngine<Customer> engine =
new FileHelperEngine<Customer>(Customer.class);
List<Customer> customers =
new ArrayList<Customer>();
customers = engine.readResource(
"/samples/customers-fixed.txt");
И у Вас будет набор проанализированных объектов.
Hope, которая помогает!
Я знаю, что Вы попросили Java, но это кажется мне задачей, хорошо подходящей для языка сценариев. Вот быстрое (очень простое) решение, записанное в Groovy.
Записи test.csv
string,float1,float2,integer
hello world,1.0,3.3,4
goodbye world,1e9,-3.3,45
hello again,-1,23.33,456
hello world 3,1.40,34.83,4999
hello 2 world,9981.05,43.33,444
csvtoxml.groovy
#!/usr/bin/env groovy
def csvdata = []
new File("test.csv").eachLine { line ->
csvdata << line.split(',')
}
def headers = csvdata[0]
def dataRows = csvdata[1..-1]
def xml = new groovy.xml.MarkupBuilder()
// write 'root' element
xml.root {
dataRows.eachWithIndex { dataRow, index ->
// write 'entry' element with 'id' attribute
entry(id:index+1) {
headers.eachWithIndex { heading, i ->
// write each heading with associated content
"${heading}"(dataRow[i])
}
}
}
}
следующий XML к stdout:
<root>
<entry id='1'>
<string>hello world</string>
<float1>1.0</float1>
<float2>3.3</float2>
<integer>4</integer>
</entry>
<entry id='2'>
<string>goodbye world</string>
<float1>1e9</float1>
<float2>-3.3</float2>
<integer>45</integer>
</entry>
<entry id='3'>
<string>hello again</string>
<float1>-1</float1>
<float2>23.33</float2>
<integer>456</integer>
</entry>
<entry id='4'>
<string>hello world 3</string>
<float1>1.40</float1>
<float2>34.83</float2>
<integer>4999</integer>
</entry>
<entry id='5'>
<string>hello 2 world</string>
<float1>9981.05</float1>
<float2>43.33</float2>
<integer>444</integer>
</entry>
</root>
Однако код делает очень простой парсинг (не принимающий во внимание заключенные в кавычки или оставленные запятые), и это не составляет возможные отсутствующие данные.
Как другие выше, я не знаю любой-шаг способ сделать это, но если бы Вы готовы пользоваться очень простыми внешними библиотеками, я предложил бы:
OpenCsv для парсинга CSV (маленький, простой, надежный и простой в использовании)
Xstream для анализирования/сериализирования XML (очень очень простой в использовании, и создание полностью человекочитаемого xml)
Используя те же демонстрационные данные как выше код был бы похож:
package fr.megiste.test;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import au.com.bytecode.opencsv.CSVReader;
import com.thoughtworks.xstream.XStream;
public class CsvToXml {
public static void main(String[] args) {
String startFile = "./startData.csv";
String outFile = "./outData.xml";
try {
CSVReader reader = new CSVReader(new FileReader(startFile));
String[] line = null;
String[] header = reader.readNext();
List out = new ArrayList();
while((line = reader.readNext())!=null){
List<String[]> item = new ArrayList<String[]>();
for (int i = 0; i < header.length; i++) {
String[] keyVal = new String[2];
String string = header[i];
String val = line[i];
keyVal[0] = string;
keyVal[1] = val;
item.add(keyVal);
}
out.add(item);
}
XStream xstream = new XStream();
xstream.toXML(out, new FileWriter(outFile,false));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Приведение к следующему результату: (Xstream позволяет очень точно настраивающий из результата...)
<list>
<list>
<string-array>
<string>string</string>
<string>hello world</string>
</string-array>
<string-array>
<string>float1</string>
<string>1.0</string>
</string-array>
<string-array>
<string>float2</string>
<string>3.3</string>
</string-array>
<string-array>
<string>integer</string>
<string>4</string>
</string-array>
</list>
<list>
<string-array>
<string>string</string>
<string>goodbye world</string>
</string-array>
<string-array>
<string>float1</string>
<string>1e9</string>
</string-array>
<string-array>
<string>float2</string>
<string>-3.3</string>
</string-array>
<string-array>
<string>integer</string>
<string>45</string>
</string-array>
</list>
<list>
<string-array>
<string>string</string>
<string>hello again</string>
</string-array>
<string-array>
<string>float1</string>
<string>-1</string>
</string-array>
<string-array>
<string>float2</string>
<string>23.33</string>
</string-array>
<string-array>
<string>integer</string>
<string>456</string>
</string-array>
</list>
<list>
<string-array>
<string>string</string>
<string>hello world 3</string>
</string-array>
<string-array>
<string>float1</string>
<string>1.40</string>
</string-array>
<string-array>
<string>float2</string>
<string>34.83</string>
</string-array>
<string-array>
<string>integer</string>
<string>4999</string>
</string-array>
</list>
<list>
<string-array>
<string>string</string>
<string>hello 2 world</string>
</string-array>
<string-array>
<string>float1</string>
<string>9981.05</string>
</string-array>
<string-array>
<string>float2</string>
<string>43.33</string>
</string-array>
<string-array>
<string>integer</string>
<string>444</string>
</string-array>
</list>
</list>
Можно сделать этот исключительно легко использующий Groovy, и код очень читаем.
В основном, текстовая переменная будет записана в contacts.xml
для каждой строки в эти contactData.csv
, и массив fields содержит каждый столбец.
def file1 = new File('c:\\temp\\ContactData.csv')
def file2 = new File('c:\\temp\\contacts.xml')
def reader = new FileReader(file1)
def writer = new FileWriter(file2)
reader.transformLine(writer) { line ->
fields = line.split(',')
text = """<CLIENTS>
<firstname> ${fields[2]} </firstname>
<surname> ${fields[1]} </surname>
<email> ${fields[9]} </email>
<employeenumber> password </employeenumber>
<title> ${fields[4]} </title>
<phone> ${fields[3]} </phone>
</CLIENTS>"""
}
Большая разница в том, что JSefa приносит то, что он может сериализовать ваши java-объекты в файлы CSV / XML / и т.д. и может десериализовать обратно в java-объекты. И это связано с аннотациями, которые дают вам полный контроль над выводом.
JFileHelpers тоже выглядит интересно.