Вот ответ на мой собственный вопрос. Я объединил ответы из различных результатов, чтобы написать класс, который прекрасно печатает XML.
Нет гарантий того, как он отвечает недействительным XML или большими документами.
package ecb.sdw.pretty;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
/**
* Pretty-prints xml, supplied as a string.
* <p/>
* eg.
* <code>
* String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");
* </code>
*/
public class XmlFormatter {
public XmlFormatter() {
}
public String format(String unformattedXml) {
try {
final Document document = parseXmlFile(unformattedXml);
OutputFormat format = new OutputFormat(document);
format.setLineWidth(65);
format.setIndenting(true);
format.setIndent(2);
Writer out = new StringWriter();
XMLSerializer serializer = new XMLSerializer(out, format);
serializer.serialize(document);
return out.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Document parseXmlFile(String in) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(in));
return db.parse(is);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String unformattedXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +
" xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +
" xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +
" <Query>\n" +
" <query:CategorySchemeWhere>\n" +
" \t\t\t\t\t <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +
" </query:CategorySchemeWhere>\n" +
" </Query>\n\n\n\n\n" +
"</QueryMessage>";
System.out.println(new XmlFormatter().format(unformattedXml));
}
}
Вы также можете включить свой фильтр someString
с LINQ.
var matches = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
var textMatches = from Match m in matches
where m.Groups["text"].Value.Equals(someString)
select m;
foreach (Match m in textMatches)
{
// Do stuff
}
Обратите внимание, что компилятор переводит такой запрос ...
var q = from MyType x in myEnum select x;
... в этот ...
var q = from x in myEnum.Cast<MyType>() select x;
... поэтому включая тип и Cast
является избыточным.
С точки зрения производительности, Cast
просто выполняет явное приведение типа и возвращает значение, поэтому снижение производительности будет незначительным. Для устаревших коллекций, где вы не уверены, что все члены принадлежат к желаемому типу, вы можете вместо этого использовать OfType
.
Try to use the Cast extension method which will return an IEnumerable.
IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>()
select m;
And event if you don't use the Cast method the compiler will infer the type of "query" to IEnumerable.
var query = from Match v in fieldValues
select v;