Не нет. Это используется для преобразования значения в булевскую переменную:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
обычно не необходимо использовать, хотя, так как единственные ложные значения к Ruby nil
и false
, таким образом, обычно лучше позволить той конвенции стоять.
Думают о нем как [1 111]
!(!some_val)
Одна вещь, которая является используемым для, законно препятствует тому, чтобы был возвращен огромный блок данных. Например, Вы, вероятно, не хотите возвращать 3 МБ данных изображения в Вашем has_image?
метод, или Вы не можете хотеть возвращать свой весь пользовательский объект в logged_in?
метод. Используя !!
преобразовывает эти объекты в простое true
/ false
.
Как говорит Эймон, если вы знаете, что элемент Xml> будет всегда, просто остановитесь на нем.
В противном случае ищите конечный тег уровня документа. То есть просканируйте текст, считая, на сколько уровней вы находитесь. Каждый раз, когда вы видите тег, который начинается с «<», но не «» и не заканчивается «/>», добавьте 1 к счетчику глубины. Каждый раз, когда вы видите тэг, начинающийся с «», вычтите 1. Каждый раз, когда вы вычитаете 1, проверяйте, находитесь ли вы на нуле. Если это так, значит, вы достигли конца XML-документа.
Не разделяйте! Добавьте вокруг него одну большую метку! Затем он снова становится одним файлом XML:
<BIGTAG>
<?xml version="1.0" encoding="UTF-8"?>
<someData>...</someData>
<?xml version="1.0" encoding="UTF-8"?>
<someData>...</someData>
<?xml version="1.0" encoding="UTF-8"?>
<someData>...</someData>
</BIGTAG>
Теперь использование / BIGTAG / SomeData предоставит вам все корни XML.
Объединив их в один файл, вы изменили кодировку ...
Поскольку вы не уверены, что объявление всегда будет присутствовать, вы можете удалить все объявления (такое регулярное выражение, как <\? Xml version. * \?>
может найти их), добавить
, добавить
, чтобы результирующая строка была допустимым XML-документом. В нем вы можете получить отдельные документы, используя (например) запрос XPath / doc-collection / *
. Если объединенный файл может быть достаточно большим, чтобы потребление памяти стало проблемой, вам может потребоваться использовать потоковый синтаксический анализатор, такой как Sax, но принцип остается тем же.
В аналогичном сценарии, с которым я столкнулся, я просто читал объединенные документ напрямую с помощью синтаксического анализатора xml: хотя объединенный файл может не быть действительным xml документом , это действительный xml фрагмент (за исключением повторяющихся объявлений) - так что после удаления объявлений, если ваш синтаксический анализатор поддерживает синтаксический анализ фрагментов, вы также можете просто прочитать результат напрямую. Тогда все элементы верхнего уровня будут корневыми элементами объединенных документов.
Короче говоря, если вы удалите все объявления, у вас будет действительный xml-фрагмент, который можно тривиально проанализировать либо напрямую, либо окружив его некоторым тегом.
У меня нет ответа на Java, но вот как я решил эту проблему с помощью C #.
Я создал класс с именем XmlFileStreams для сканирования исходного документа на предмет объявления XML-документа и логического разделения его на несколько документов:
class XmlFileStreams {
List<int> positions = new List<int>();
byte[] bytes;
public XmlFileStreams(string filename) {
bytes = File.ReadAllBytes(filename);
for (int pos = 0; pos < bytes.Length - 5; ++pos)
if (bytes[pos] == '<' && bytes[pos + 1] == '?' && bytes[pos + 2] == 'x' && bytes[pos + 3] == 'm' && bytes[pos + 4] == 'l')
positions.Add(pos);
positions.Add(bytes.Length);
}
public IEnumerable<Stream> Streams {
get {
if (positions.Count > 1)
for (int i = 0; i < positions.Count - 1; ++i)
yield return new MemoryStream(bytes, positions[i], positions[i + 1] - positions[i]);
}
}
}
Чтобы использовать XmlFileStreams:
foreach (Stream stream in new XmlFileStreams(@"c:\tmp\test.xml").Streams) {
using (var xr = XmlReader.Create(stream, new XmlReaderSettings() { XmlResolver = null, ProhibitDtd = false })) {
// parse file using xr
}
}
Есть несколько предостережений.