Java XML Pretty Print with Commented blocks - pretty-print

I have below code to pretty print a given XML.
public void prettyPrintXML(String xmlString) {
try {
Source xmlInput = new StreamSource(new StringReader(xmlString));
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(xmlInput, xmlOutput);
System.out.println("OutPutXML : ");
System.out.println(xmlOutput.getWriter().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
Here is an input and output of the above code:
InputXML :
<employees><employee><name>John</name><age>18</age></employee><!--employee><name>Smith</name><age>27</age></employee--></employees>
OutPutXML :
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee>
<name>John</name>
<age>18</age>
</employee>
<!--employee><name>Smith</name><age>27</age></employee-->
</employees>
I need to get the commented block in above output in below format
<!--employee>
<name>Smith</name>
<age>27</age>
</employee-->
Is there a way to do this in Java without using any external libraries?

No, this is not supported out of the box using the standard libraries. Getting that kind of behaviour requires tweaking a lot; parsing the comment as XML and inheriting the indentation level from the parent node. You also run the risk of mixing comments containing plain text with those containing XML.
I have however implemented such a processor: xmlformatter. It also handles XML in text and CDATA nodes, and can do so robustly (i.e. does not fail on invalid XML within comments).
From
<parent><child><!--<comment><xml/></comment>--></child></parent>
you'll get
<parent>
<child>
<!--
<comment>
<xml/>
</comment>-->
</child>
</parent>
which I think will be a bit more readable than your desired output.

Related

Wrong language codes generated by Windows.Globalization.ApplicationLanguages.ManifestLanguages

I am localizing my UWP app in several languages using the Multilingual App Toolkit
here are some screen shots of how the MultilingualResourcesFolder and the Strings folder looks like in the project
Multilingual Resources
Strings
All the files are filled with the correct values.
In the application I retrieve the list of available languages with
Windows.Globalization.ApplicationLanguages.ManifestLanguages and iterate through them. The iteration yields these results
pt-PT
ro-RO
ru
sk
sl
This is very strange because the languages are declared in exaclty the same way but for some languages the language code includes the locale and for some it doesn't , for no reason I can undestand.
In the way I declare them the iteration should yield
pt-PT
ro-RO
ru-RU
sk-SK
sl-SL
I have tried manually declaring the languages in the appxmanifest by replacing x-generate like this
<Resources>
<Resource Language="ru-ru"/>
<Resource Language="sk-sk"/>
<Resource Language="pt-pt"/>
<Resource Language="sk-sk"/>
<Resource Language="sl-sl"/>
</Resources
but the results are the same.
I need to get the application to recognize the locale as well as the language for every language.
Can anybody help?
Ok, I've got a solution for you. There's also a separate issue that you're dealing with, which is why x-generate in the manifest isn't doing the right thing (or is it?). I'm investigating that on the side.
So, this is the method you want:
public static string GetLocaleFromLanguage(string identifier)
{
int result;
StringBuilder localeName = new StringBuilder(500);
result = LocaleFunctions.ResolveLocaleName(identifier, localeName, 500);
StringBuilder localeDisplay = new StringBuilder(500);
result = LocaleFunctions.GetLocaleInfoEx(localeName.ToString(), LCTYPE.LOCALE_SENGLISHDISPLAYNAME, localeDisplay, 500);
return localeDisplay.ToString();
}
And of course, you're going to need the externs:
class LocaleFunctions
{
// pInvoke declarations
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetLocaleInfoEx(String lpLocaleName, LCTYPE LCType, StringBuilder lpLCData, int cchData);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int ResolveLocaleName(string lpNameToResolve, StringBuilder lpLocaleName, int cchLocaleName);
}
Unfortunately, you're also going to need the declaration for LCTYPE. The code for that can be found at this link: http://www.pinvoke.net/default.aspx/Enums/LCTYPE.html
(It's a massive chunk of code and I don't want to just copy that here.
In my code, I manually added the following language resources to my manifest (again, I'm not sure why x-generate isn't adding the Russian locales here, but this works around it):
<Resources>
<Resource Language="EN-US" />
<Resource Language="ES-ES" />
<Resource Language="ES-MX" />
<Resource Language="PT-PT" />
<Resource Language="RO-RO" />
<Resource Language="RU-RU" />
<Resource Language="RU-UA" />
</Resources>
And this is the method I'm using to call in:
private void button_Click(object sender, RoutedEventArgs e)
{
string output = "";
foreach (string thisManifestLanguage in Windows.Globalization.ApplicationLanguages.ManifestLanguages)
{
output += thisManifestLanguage + ": ";
string ResolvedName = LocalizationTesting.LocaleTest.GetLocaleFromLanguage(thisManifestLanguage);
output += ResolvedName + "\n";
}
this.outputText.Text = output;
}
When I called this, the output I got was:
en-US: English (United States)
es-ES: Spanish (Spain, International Sort)
es-MX: Spanish (Mexico)
pt-PT: Portuguese (Portugal)
ro-RO: Romanian (Romania)
ru: Russian (Russia)
ru-UA: Russian (Ukraine)
I should point out that in GetLocaleFromLanguage, localeName for "ru" gets "ru-RU", so if that's what you're looking for, that's available too.
Let me know if this doesn't meet with your needs. I'll see if I can get a reason about why in my case, I had to explicitly add ru-UA to my manifest.
I'll let Dante follow up, but I'm curious why this list is interesting? Eg: What's the user scenario?
A UWP lists the languages it can provide data for, and the Region & Language Settings collects a list of languages that the user understands. So then Windows figures out which language best matches the user and app language and the resource loader uses that. So I'm curious what scenario is missing?

Add Resource Bundles Programmatically

I have a faces-config.xml file with some resource bundles declared, like this:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>de</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>pt</supported-locale>
<supported-locale>zh</supported-locale>
</locale-config>
<resource-bundle>
<base-name>messages.Messages</base-name>
<var>bundle</var>
</resource-bundle>
<resource-bundle>
<base-name>countries.Countries</base-name>
<var>countryBundle</var>
</resource-bundle>
</application>
</faces-config>
These resource bundles are registered and can be used in any .xhtml file, but is there any way to register these resource bundles programmatically? I mean by the use of dynamic code instead of a xml declaration.
Here's a simplified version of what I'm doing using CDI:
#ApplicationScoped
public class BundleProducer {
#Produce #RequestScoped #Named
public ResourceBundle getMsgBundle() {
Locale userLocale = Faces.getLocale();
return ResourceBundle.getBundle("messages", userLocale);
}
}
Note the use of omnifaces' getLocale() to avoid a ton of boilerplace code (for a less sane version, you can substitute FacesContext.getCurrentInstance().getViewRoot().getLocale() like in the tutorial you linked to).
This will cause the CDI framework to call getMsgBundle once each request if it needs to access to msgBundle thanks to the #Named annotation. In this simple case, I'm relying on the ResourceBundle internal caching and lookup mechanisms to produce my bundle efficiently. You can execute any logic you like here (eg, load stuff from the enclosing BundleProducer) as long as you return a ResourceBundle from the method (you're not allowed to return null).
Repeat as you like with more methods producing different bundles.
Not sure if I got what you were after, so just comment if you need more clarification.
For easier handling of FacesMessage stuff, I'd recommend having a look at omnifaces' Messages utility class. I use something like this to be able to optionally give bundle keys as message strings:
#Singleton
#Startup
public class MessageResolverInit {
#PostConstruct
public void initMessageResolver() {
Messages.setResolver(new Messages.Resolver() {
#Override
public String getMessage(String message, Object... params) {
Locale userLocale = Faces.getLocale();
ResourceBundle b = ResourceBundle.getBundle("msgs", userLocale);
if (b.containsKey(message)) {
return MessageFormat.format(b.getString(message), params);
}
return message;
}
});
}
Note that I use b as a variable name only for demo purposes. Usage goes like this:
Messages.addGlobalError("my_msg_key", param1);
Messages.addGlobalInfo("I'm a standalone message");
Here is the answer from Oracle documentation: Using FacesMessage to Create a Message

How to add Apache Any23 RDF Statements to Apache Jena?

Basically, I use the Any23 distiller to extract RDF statements from files embedded with RDFa (The actual files where created by DBpedia Spotlight using the xhtml+xml output option). By using Any23 RDFa distiller I can extract the RDF statements (I also tried using Java-RDFa but I could only extract the prefixes!). However, when I try to pass the statements to a Jena model and print the results to the console, nothing happens!
This is the code I am using :
File myFile = new File("T1");
Any23 runner= new Any23();
DocumentSource source = new FileDocumentSource(myFile);
ByteArrayOutputStream outA = new ByteArrayOutputStream();
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()); //convert the output stream to input so i can pass it to jena model
TripleHandler writer = new NTriplesWriter(outA);
try {
runner.extract(source, writer);
} finally {
writer.close();
}
String ttl = outA.toString("UTF-8");
System.out.println(ttl);
System.out.println();
System.out.println();
Model model = ModelFactory.createDefaultModel();
model.read(decodedInput, null, "N-TRIPLE");
model.write(System.out, "TURTLE"); // prints nothing!
Can anyone tell me what I have done wrong? Probably multiple things!
Is there any easy way i can extract the subjects of the RDF statements directly from any23 (bypassing Jena)?
As I am quite inexperienced in programming any help would be really appreciated!
You are calling
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()) ;
before calling any23 to insert triples. At the point of the call, it's empty.
Move this after the try-catch block.

FOP: how to specify image src relative path?

This is my first question here, i hope i'm doing it right. Sorry for my bad English in advance :)
I am using JSF 2.0 (Eclipse IDE) and i'm trying to generate some PDF files using Apache FOP 1.0.
I was able to make simple PDF files using instructions on Apache Fop site , but i can't insert any image from my application folder. My folder structure is like this:
In my application WebContent i have (among else)
pdf_transform/xslt/transformFile.xsl, and
pdf_transform/xslt/logo.jpg
In transformFile.xsl i have
<fo:block><fo:external-graphic src="url('logo.jpg')"/></fo:block>
but when i clik 'showPDF' button in my servlet, i get PDF file without image (everything else is there), and this messages in console:
SEVERE: The Source that was returned
from URI resolution didn't contain an
InputStream for URI: logo.jpg Nov 18,
2010 5:16:49 PM
org.apache.fop.events.LoggingEventListener
processEvent SEVERE: Image not found.
URI: logo.jpg. (No context info
available)
I tried to use 'logo.jpg' instead of url('logo.jpg'), putting image on various places inside WebContent folder and using different navigation("./logo.jpg") but it didnt work.
It works fine if i set absolute path (for example "d:/fop/images/logo.jpg") but i need resurces whitin my application.
While searching, i found that this is related to fopFactory.setURIResolver() and/or userAgent.setBaseURL(). Tried something with that, but didnt succeed.
I am new to both JSF and FOP, and this image situation has been bothering me quite a while. Can someone help me with this, or at least direct me to some tutorial on "how to configure FOP for relative path use"?
EDIT: I don't want any absolute paths and app should work independently of its location on computer (to be publishable). My search tells me it has something to do with configuring FOP, but i don't know how to do it :)
Thanks in advance.
P.S. This is method which is called to display PDF:
public void printExchangeRateList(ActionEvent event) {
BufferedOutputStream output = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
String path = externalContext.getRealPath("/");
try {
response.reset();
response.setHeader("Content-Type", "application/pdf");
output = new BufferedOutputStream(response.getOutputStream(), 10240);
File xsltfile = new File(path+"/pdf_transform/xslt/transformFile.xsl");
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltfile));
Source src = new DOMSource(makeXML()); // my method
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} finally {
if (output != null) output.close();
/*try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
} catch (Exception e) {
// TODO Auto-generated catch block
}
facesContext.responseComplete();
}
i found solution to my problem. I thought i tried that, but it seems i made some little mistake back then. Anyway, with the following code
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String basePath = externalContext.getRealPath("/");
FopFactory fopFactory = FopFactory.newInstance();
fopFactory.setBaseURL(basePath);
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.setBaseURL(fopFactory.getBaseURL());
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, output); // for some output
you can access your images (and other resources) from your xslt file using relative path starting from your application's WebContent folder. In my case, i can access logo.jpg like this
<fo:external-graphic src="url('pdf_transform/xslt/logo.jpg')"/>
Took me time to figure out this, i don't get it why no examples with such basic thing on the net (or i can't find them :)
Note: In FOP 2.0 there is no setBaseURL() method. Instead you pass the base URL as a parameter to FopFactory.newInstance(). Many of the other setters have been moved to FopFactoryBuilder.
If you have access to the web url for the pictures you can use that as well when generating reports, ie http://localhost/images/logo.jpg .
But while I still had images locally on the web server, I included the path to the application in the XML file and used it like this:
<xsl:variable name="base_path" select="base-path"/>
<xsl:variable name="logo" select="companies/company/logo"/>
<fo:external-graphic src="url({$base_path}{logo})"/>
Where the XML structure might be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<base-path>/path/to/app/</base-path>
<companies>
<company>
<logo>images/company1.jpg</logo>
</company>
<company>
<logo>images/company2.jpg</logo>
</company>
</companies>
I had the same problem and tried this solution:
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
Request request = RequestCycle.get().getRequest();
//sort of a hack to find the path to the files that are in /img folder.
String baseUrl = request.getUrl().getProtocol()+"://"+request.getUrl().getHost()+":"+request.getUrl().getPort();
foUserAgent.setBaseURL(baseUrl);
Then, on XSL I used:
<fo:external-graphic src="/img/image.png" />
To test if this is working, you should be able to see the image on protocol://link:port/img/image.png

How to generate an HTML report from PartCover results .xml

How to generate an HTML report from PartCover results .xml
There is a tool you can use to generate a HTML report:
https://github.com/danielpalme/ReportGenerator
Here you can find an article how to integrate the tool into MSBuild:
http://www.palmmedia.de/Blog/2009/10/30/msbuild-code-coverage-analysis-with-partcover-and-reportgenerator
To my knowledge, there is no convenient tool like NCoverExplorer that can transform a PartCover results .xml file into a .html report, but there are some .xsl files that can be used to transform PartCover's results to .html in CruiseControl.NET: Using CruiseControl.NET with PartCover.
You could take those .xsl files from CruiseControl.NET and convert your PartCover results.xml using something like Sandcastle's XslTransform.exe.
By the way, if this happens to be related to TeamCity, the upcoming 5.0 release will include support for .NET coverage using PartCover or NCover. See the documentation for more informations. Otherwise ignore this paragraph ;-)
Easiest solution is probably to use msxsl, a simple command line transformer. I use it for exactly this purpose, and it's easy to integrate into your build system.
http://www.microsoft.com/downloads/details.aspx?FamilyID=2FB55371-C94E-4373-B0E9-DB4816552E41&displaylang=en
Maybe a complicated way of doing it, but I did this with the Simian xml report. Created an XSL file for the formatting, then wrote a dumb little console application;
private const string MissingExtension = "Please enter a valid {0} file, this is missing the extension.";
private const string InvalidExtension = "Please enter a valid {0} file, the file provided has an invalid extension.";
public static void Main(string[] args)
{
if (args.Length < 2)
{
System.Console.WriteLine("Please enter a xsl file and xml file full path.");
return;
}
var xslFile = args[0];
var xmlFile = args[1];
if (!CheckFileNameFormat(xslFile, false))
return;
if (!CheckFileNameFormat(xmlFile, true))
return;
var transform = new XslCompiledTransform();
// Load the XSL stylesheet.
transform.Load(xslFile);
// Transform xml file into an html using the xsl file provided.
transform.Transform(xmlFile, xmlFile.Replace("xml", "html"));
}
private static bool CheckFileNameFormat(string fileName, bool isXmlFile)
{
var extension = isXmlFile ? "xml" : "xsl";
// valida that the argument has a period
if (fileName.IndexOf(".") < 1)
{
System.Console.WriteLine(string.Format(MissingExtension, extension));
return false;
}
var filePieces = fileName.Split('.');
// split on the period and make sure the extension is valid
if (filePieces[filePieces.GetUpperBound(0)] != extension)
{
System.Console.WriteLine(string.Format(InvalidExtension, extension));
return false;
}
return true;
}
Then I can call it from a MSBuild file like so;
<Target Name="RunSimian" DependsOnTargets="RebuildSolution">
<Exec IgnoreExitCode="true" Command=""$(MSBuildProjectDirectory)\..\Build\Packages\Simian\simian-2.2.24.exe" -formatter=xml:$(MSBuildProjectDirectory)\..\Build\Artifacts\simian.xml -language=cs -excludes=$(MSBuildProjectDirectory)\..\Product\Production\**\*.Designer.cs $(MSBuildProjectDirectory)\Production\**\*.cs" >
</Exec>
<Exec IgnoreExitCode="true" Command=""$(MSBuildProjectDirectory)\..\Build\Packages\XmlToHtmlConverter.exe" $(MSBuildProjectDirectory)\..\Build\Packages\Simian\simian.xsl $(MSBuildProjectDirectory)\..\Build\Artifacts\simian.xml">
</Exec>

Resources