cannot get cdata result using xstream, stax2, woodstox - java

sample xml
<root>
<first>
<second><![CDATA[hello, world]]></second>
</first>
<root>
I'm using xstream(1.4.7), stax2-api(3.1.4), woodstox(5.0.3).
#Test
public void xmlInputFactoryTest() throws XMLStreamException, IOException {
ClassPathResource resource = new ClassPathResource("/sample/input.xml");
NameCoder nameCoder = new XmlFriendlyNameCoder();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader reader = factory.createXMLEventReader(resource.getInputStream());
XMLStreamReader streamReader = StaxUtils.createEventStreamReader(reader);
HierarchicalStreamReader hsr = new StaxReader(new QNameMap(), streamReader, nameCoder);
write(hsr);
}
public void write(HierarchicalStreamReader hsr) {
System.out.println(hsr.getNodeName() + ", " + hsr.getValue()); // should be print "hello,world" in second tag
if (hsr.hasMoreChildren()) {
hsr.moveDown();
write(hsr);
}
}
here is my sample test code
I can not get cdata string result in path "root/first/second"
I think XMLInputFactory.newInstance() return class affect to result.
when I add
factory.setProperty(XMLInputFactory.IS_COALESCING, true);
this code after get XMLInputFactory.newInstance().
It works.
but it does not seem to be the answer.
.
Is not version compatible?
Is there any other way possible?

Related

Element being returned as NULL when parsing through StAX

I am trying to read a attribute of an element of a XML file and for that I am using the library jdom2 and Stax.
private String readIncludeAll(String filePath) throws JDOMException, IOException, XMLStreamException {
String includeAll = null;
Document document = getStAXParsedDocument(filePath);
Element rootNode = document.getRootElement();
logger.info("ROOT: "+rootNode );
List <Element> children=rootNode.getChildren();
for(int i=0;i<children.size();i++){
logger.info("CHILDREN:" +children.get(i).toString());
}
Element includeElement=rootNode.getChild("includeAll");
logger.info("INCLUDE ELEMENT: "+includeElement);
// includeAll=includeElement.getAttributeValue("path");
//logger.info("VALOR DE PATH: "+includeAll);
return includeAll;
}
private Document getStAXParsedDocument(final String fileName) throws JDOMException, FileNotFoundException, XMLStreamException {
XMLInputFactory factory = XMLInputFactory.newFactory();
XMLEventReader reader = factory.createXMLEventReader(new FileReader(fileName));
StAXEventBuilder builder = new StAXEventBuilder();
return builder.build(reader);
}
I've tried printing in the console the children of the root element and includeAll is indeed a child of root element. Why is it being returned as NULL?
ROOT: [Element: <databaseChangeLog [Namespace: http://www.liquibase.org/xml/ns/dbchangelog]/>]
CHILDREN:[Element: <includeAll [Namespace: http://www.liquibase.org/xml/ns/dbchangelog]/>]
INCLUDE ELEMENT: null
Use the overload of getChild that takes a local name and a namespace http://www.jdom.org/docs/apidocs/org/jdom2/Element.html#getChild(java.lang.String,%20org.jdom2.Namespace) i.e. rootNode.getChild("includeAll", Namespace.get("http://www.liquibase.org/xml/ns/dbchangelog"))

How to bind input externally to xquery using saxon?

I have to invoke external java methods in xquery using saxon HE. I could able to invoke the methods with the below code. But the problem is i want to bind my input externally.
final Configuration config = new Configuration();
config.registerExtensionFunction(new ShiftLeft());
final StaticQueryContext sqc = new StaticQueryContext(config);
final XQueryExpression exp = sqc.compileQuery(new FileReader(
"input/names.xq"));
final DynamicQueryContext dynamicContext = new DynamicQueryContext(config);
String xml = "<student_list><student><name>George Washington</name><major>Politics</major><phone>312-123-4567</phone><email>gw#example.edu</email></student><student><name>Janet Jones</name><major>Undeclared</major><phone>311-122-2233</phone><email>janetj#example.edu</email></student><student><name>Joe Taylor</name><major>Engineering</major><phone>211-111-2333</phone><email>joe#example.edu</email></student></student_list>";
DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance();
newInstance.setNamespaceAware(true);
Document parse = newInstance.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
DocumentWrapper sequence = new DocumentWrapper(parse, "", config);
StructuredQName qname = new StructuredQName("", "", "student_list");
dynamicContext.setParameter(qname, sequence);
Properties props = new Properties();
final SequenceIterator iter = exp.iterator(dynamicContext);
props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
props.setProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
QueryResult.serializeSequence(iter, config, writer, props);
System.out.println("Result is " + writer);
names.xq
declare namespace eg="http://example.com/saxon-extension";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare variable $student_list as element(*) external;
<Students>
<value> {
let $n := eg:shift-left(2, 2)
return $n
}</value>
<student_names>
{ $student_list//student_list/student/name }
</student_names>
</Students>
But getting the below error
Error at procedure student_list on line 3 of students.xml:
XPTY0004: Required item type of value of variable $student_list is element(); supplied
value has item type document-node(element(Q{}student_list))
net.sf.saxon.trans.XPathException: Required item type of value of variable $student_list is element(); supplied value has item type document- node(element(Q{}student_list))
at net.sf.saxon.expr.ItemTypeCheckingFunction.testConformance(ItemTypeCheckingFunction.java:69)
at net.sf.saxon.expr.ItemTypeCheckingFunction.mapItem(ItemTypeCheckingFunction.java:50)
at net.sf.saxon.expr.ItemMappingIterator.next(ItemMappingIterator.java:95)
at net.sf.saxon.expr.CardinalityCheckingIterator.<init>(CardinalityCheckingIterator.java:52)
at net.sf.saxon.type.TypeHierarchy.applyFunctionConversionRules(TypeHierarchy.java:230)
at net.sf.saxon.expr.instruct.GlobalParameterSet.convertParameterValue(GlobalParameterSet.java:105)
at net.sf.saxon.expr.instruct.Bindery.useGlobalParameter(Bindery.java:136)
at net.sf.saxon.expr.instruct.GlobalParam.evaluateVariable(GlobalParam.java:62)
at net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:105)
at net.sf.saxon.expr.VariableReference.evaluateItem(VariableReference.java:460)
at net.sf.saxon.expr.Atomizer.evaluateItem(Atomizer.java:313)
at net.sf.saxon.expr.Atomizer.evaluateItem(Atomizer.java:35)
at net.sf.saxon.expr.AtomicSequenceConverter.evaluateItem(AtomicSequenceConverter.java:275)
at net.sf.saxon.expr.AtomicSequenceConverter.evaluateItem(AtomicSequenceConverter.java:30)
at net.sf.saxon.functions.Doc.doc(Doc.java:235)
at net.sf.saxon.functions.Doc.evaluateItem(Doc.java:190)
at net.sf.saxon.functions.Doc.evaluateItem(Doc.java:28)
at net.sf.saxon.expr.SimpleStepExpression.iterate(SimpleStepExpression.java:85)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:842)
at net.sf.saxon.expr.sort.DocumentSorter.iterate(DocumentSorter.java:168)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:842)
at net.sf.saxon.expr.sort.DocumentSorter.iterate(DocumentSorter.java:168)
at net.sf.saxon.expr.Expression.process(Expression.java:552)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
at net.sf.saxon.expr.instruct.ElementCreator.constructElement(ElementCreator.java:539)
at net.sf.saxon.expr.instruct.ElementCreator.evaluateItem(ElementCreator.java:476)
at net.sf.saxon.expr.instruct.Instruction.iterate(Instruction.java:363)
at net.sf.saxon.query.XQueryExpression.iterator(XQueryExpression.java:332)
at com.example.saxon.ExternalMethodCaller.main(ExternalMethodCaller.java:77)
Thanks in advance..
Unless you have a very good reason not to, my advice is to use Snappi (the Saxon 9 API, or s9api):
Processor saxon = new Processor(false);
saxon.registerExtensionFunction(new MyExtension());
XQueryCompiler compiler = saxon.newXQueryCompiler();
XQueryExecutable exec = compiler.compile(new File("input/names.xq"));
XQueryEvaluator query = exec.load();
DocumentBuilder builder = saxon.newDocumentBuilder();
String students = "<xml>...</xml>";
Source src = new StreamSource(new StringReader(students));
XdmNode doc = builder.build(src);
query.setExternalVariable(new QName("student_list"), doc);
XdmValue result = query.evaluate();
With MyExtension looking something like the following:
public class MyExtension
implements ExtensionFunction
{
#Override
public QName getName()
{
return new QName("http://example.org/my-project", "my-fun");
}
#Override
public SequenceType getResultType()
{
return SequenceType.makeSequenceType(
ItemType.INTEGER, OccurrenceIndicator.ONE);
}
#Override
public SequenceType[] getArgumentTypes()
{
return new SequenceType[] {
SequenceType.makeSequenceType(
ItemType.INTEGER, OccurrenceIndicator.ONE),
SequenceType.makeSequenceType(
ItemType.INTEGER, OccurrenceIndicator.ONE)
};
}
#Override
public XdmValue call(XdmValue[] args) throws SaxonApiException
{
long first = ((XdmAtomicValue)args[0].itemAt(0)).getLongValue();
long second = ((XdmAtomicValue)args[0].itemAt(0)).getLongValue();
long result = ...;
return new XdmAtomicValue(result);
}
}
See the documentation at http://www.saxonica.com/documentation9.5/extensibility/integratedfunctions/ext-simple-J.html for details.
EXPath also has a project called tools-saxon, containing several tools for using Saxon in Java. Including extension functions. It introduces the concept of a function library, which is convenient if you have several extension functions. It also introduces a function definition builder, allowing one to build a function definition with as less boiler plate code as possible (and providing convenient shortcuts for type sequences). In the above code, replace the function registering (the first 2 lines) by:
Processor saxon = new Processor(false);
Library lib = new MyLibrary();
lib.register(saxon.getUnderlyingConfiguration());
and replace the extension class with the 2 following classes (a library and a function, resp.):
public class MyLibrary
extends Library
{
public MyLibrary()
{
super("http://example.org/my-project", "my");
}
#Override
protected Function[] functions()
{
return new Function[] {
new MyFunction(this)
};
}
}
public class MyFunction
extends Function
{
public MyFunction(Library lib)
{
super(lib);
}
#Override
protected Definition makeDefinition()
{
return library()
.function(this, "my-fun")
.returns(Types.SINGLE_INTEGER)
.param(Types.SINGLE_INTEGER, "first")
.param(Types.SINGLE_INTEGER, "second")
.make();
}
#Override
public Sequence call(XPathContext ctxt, Sequence[] args)
throws XPathException
{
Parameters params = checkParams(args);
long first = params.asLong(0, true);
long second = params.asLong(1, true);
long result = 0;
return Return.value(result);
}
}
See all informatio on the project home on Github, at https://github.com/expath/tools-saxon.
Note: not tested.

Printing '<xsl:message>' from a xsl file in JTextArea

I'm always trying to print my xsl message in a JTextArea. With the Code of my last question I can print the xsl output in my TextArea, but not the message that is written in the xslt file.
Java Code:
public static void xslTransform(File xmlFile)throws IOException, TransformerException{
File xslFile = ...;
StreamSource xmlSource = new StreamSource(xmlFile);
StreamSource xslSource = new StreamSource(xslFile);
StreamResult result = new StreamResult (new StringWriter()); //maybe here is the problem?
TransformerFactory transformerFact = TransformerFactory.newInstance();
transformerFact.setAttribute(FeatureKeys.MESSAGE_EMITTER_CLASS, "MyMessageEmitter");
Transformer transformer = transformerFact.newTransformer(xslSource);
transformer.transform(xmlSource,result);
}
public class MyMessageEmitter extends net.sf.saxon.serialize.MessageEmitter{
String message;
private StringWriter stwriter = new StringWriter();
public void MyMessageEmitter() throws XPathException{
setWriter(stwriter);
}
#Override
public void close() throws XPathException{
super.close();
message=stwriter.toString();
myJTextArea.setText(message);
stwriter = new StringWriter();
}
}
The XSLT File:
<xsl:template match="/">
<xsl:for-each select="//#id">
<xsl:message>
<xsl:value-of select="name(parent::*)"/> <xsl:text></xsl:text><xsl:value-of select="."/>
</xslmessage>
</xsl:for-each>
</xsl:tempate>
with this Code message from java is empty because this xslt do not paste any output (for example a new xml-document. I checked this with another xslt that prints a new xml.
So how can i get the message that prints the xslt?
Thanks for all help
KaFu
If MyMessageEmitter has a reference to myJTextArea then presumably it is an inner class.
This means that its full name is not "MyMessageEmitter" but something more complex. With your code as written I get this:
Error
Failed to load MyMessageEmitter
net.sf.saxon.trans.XPathException: Failed to load MyMessageEmitter
at net.sf.saxon.trans.DynamicLoader.getClass(DynamicLoader.java:123)
...
Caused by: java.lang.ClassNotFoundException: MyMessageEmitter
If I change the class name in factory.setAttribute to the correct name I get this:
Error
Failed to instantiate class jaxptest.TransformMessageTest$MyMessageEmitter
net.sf.saxon.trans.XPathException: Failed to instantiate class jaxptest.TransformMessageTest$MyMessageEmitter
at net.sf.saxon.trans.DynamicLoader.getInstance(DynamicLoader.java:185)
...
Caused by: java.lang.InstantiationException: jaxptest.TransformMessageTest$MyMessageEmitter
This is because a non-static inner class cannot be instantiated except from its containing class.
Your next error is very subtle and took me a long time to diagnose. You've written
public void MyMessageEmitter() throws XPathException{
setWriter(stwriter);
}
but that makes MyMessageEmitter() an ordinary method, whereas you intended it to be a constructor. So it should have been written:
public MyMessageEmitter() throws XPathException{
setWriter(stwriter);
}
It works if I make the inner class static; but the problem now is that the static class can't simply refer to the jTextArea by name.
The next problem is also quite subtle, and this time it's Saxon that's at least half to blame: the close() method on the MessageEmitter is called twice. Unfortunately when this happens the first call creates a new empty StringWriter, and the second call writes the content of this empty StringWriter to your text area. So I changed it to create a new StringWriter in the open() method rather than in the close() method.
This now leaves the question of how to communicate between your MessageEmitter and your JTextArea. This isn't trivial. I did it by having the MessageEmitter write to a static variable, and having the callling application pick up this static variable. But obviously, use of global static variables isn't really acceptable in production applications. The problem is that Saxon creates an instance of your MessageEmitter class, but doesn't provide any direct way of communicating with it. The only solution I could find to this involved using some lower-level Saxon interfaces, like this:
public void testMessageCapture() {
try {
String stylesheet =
"<?xml version='1.0'?>" +
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
" version='2.0'>" +
" <xsl:template match='/'>" +
"<first/>" +
"<xsl:message>Hi!</xsl:message>" +
" </xsl:template>" +
"</xsl:stylesheet>";
TransformerFactory transFactory = new TransformerFactoryImpl();
//transFactory.setAttribute(FeatureKeys.MESSAGE_EMITTER_CLASS, "jaxptest.TransformMessageTest$MyMessageEmitter");
Templates templates = transFactory.newTemplates(
new SAXSource(new InputSource(new StringReader(stylesheet))));
StreamResult result = new StreamResult(new StringWriter());
final StringWriter messageOut = new StringWriter();
Transformer transformer = templates.newTransformer();
((net.sf.saxon.jaxp.TransformerImpl)transformer).getUnderlyingController().setMessageEmitter(
new MessageEmitter() {
#Override
public void open() throws XPathException {
setWriter(messageOut);
super.open();
}
}
);
transformer.transform(new StreamSource(new StringReader("<in/>")), result);
assertEquals("Hi!", messageOut.toString().trim());
} catch (TransformerException e) {
e.printStackTrace();
fail();
}
}
(where of course you could substitute the writing to the string writer with a direct write to your JTextArea).
This code is actually specific to Saxon 9.6; in earlier releases you would cast the JAXP Transformer to a Controller directly.
This rather illustrates the limitations of relying on JAXP interfaces. It would be a lot easier to do this using Saxon's native s9api interface.
I got it... Here is the solution:
Processor proc = new Processor(false);
XsltCompiler comp = new proc.newXsltCompiler();
StreamSource styleSource = new StreamSource(xsltFile);
StreamSource xmlSource = new StreamSource(xmlFile);
String msg="";
XsltExecutable templates = comp.compile(styleSource);
XsltTransformer transformer = templates.load();
transformer.setSource(xmlSource);
transformer.setMessageListener(new MessageListener(){
#Override
public void message (XdmNode content, boolean terminate, SourceLocator locator){
try{
if (content.getTypedValue!= null){
msg += content.getTypedValue().toString() + "\n";
}}
catch (SaxonApiException ex){
Logger.getLogger(...);
}
}
});
Writer write = new StringWriter();
Serializer out = proc.newSerializer(write);
transformer.setDestination(out);
transformer.transform();
textAreaOut.setText(msg);
thanks for your help!

How to generate multiple, slightly different XSD schemas from one Java model with JAXB?

I have a set of related Java classes, which are able to hold data I need. Below is a simplified class diagram of what I have:
Now I need to import data from XML and for that I want to generate XSD schema. The problem is that I want several XSD schemas like this:
One that allows the whole data graph to be imported.
One that allows only RootNote.fieldA and ChildNodeA.
One that allows only RootNote.fieldB and ChildNodeB.
I can easily generate XSD that meets the requirements of nr.1 using JAXB (programmatically). But is there a way to do that for cases nr.2 and nr.3 for the same classes? In other words, it seems I need something like "profiles" in JAXB.
Update:
Here is how I generate XSD schema:
JAXBContext jc = JAXBContext.newInstance(RootNode.class);
final File baseDir = new File(".");
class MySchemaOutputResolver extends SchemaOutputResolver {
public Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException {
return new StreamResult(new File(baseDir,suggestedFileName));
}
}
jc.generateSchema(new MySchemaOutputResolver());
This is not a full answer, just an idea.
You probably use the javax.xml.bind.JAXBContext.generateSchema(SchemaOutputResolver) method to generate your schema, so you basically use a specific JAXBContext instance. This instance is built based on the annotations in classes. When building the context, these annotations are read an organized into a model which is then used for all the operations.
So to generate different schemas you probably need to create different contexts. You can't change the annotations per case, but you can read annotations in different ways.
Take a look at the AnnotationReader. This is what JAXB RI uses behind the scenes to load annotations from Java classes. You can create your own implementation and use it when creating the JAXBContext. Here's an example of something similar:
final AnnotationReader<Type, Class, Field, Method> annotationReader = new AnnoxAnnotationReader();
final Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBRIContext.ANNOTATION_READER, annotationReader);
final JAXBContext context = JAXBContext.newInstance(
"org.jvnet.annox.samples.po",
Thread.currentThread().getContextClassLoader(),
properties);
So how about writing your own annotation reader, which would consider what you call "profiles"? You can invent your own annotation #XmlSchemaProfile(name="foo"). Your annotation reader would then check if this annotation is present with the desired value and then either return it or ignore it. You'll be able to build different contexts from the same Java model - and consequently produce different schemas according to profiles defined by your #XmlSchemaProfile annotations.
I found a solution that suited me. The idea is to output the result of XSD generation into an XML Document (in-memory DOM). JAXB allows that. After this, you can manipulate the document any way you wish, adding or removing parts.
I wrote some filters that whitelist or blacklist fields (in XSD they are elements) and classes (in XSD they are complex types). While I see a lot of potential problems with this approach, it did the job in my case. Below is the code for case 2 schema:
// This SchemaOutputResolver implementation saves XSD into DOM
static class DOMResultSchemaOutputResolver extends SchemaOutputResolver {
private List<DOMResult> results = new LinkedList<DOMResult>();
#Override
public Result createOutput(String ns, String file) throws IOException {
DOMResult result = new DOMResult();
result.setSystemId(file);
results.add(result);
return result;
}
public Document getDocument() {
return (Document)results.get(0).getNode();
}
public String getFilename() {
return results.get(0).getSystemId();
}
}
// This method serializes the DOM into file
protected void serializeXsdToFile(Document xsdDocument, String filename) throws IOException {
OutputFormat format = new OutputFormat(xsdDocument);
format.setIndenting(true);
FileOutputStream os = new FileOutputStream(filename);
XMLSerializer serializer = new XMLSerializer(os, format);
serializer.serialize(xsdDocument);
}
#Test
public void generateSchema2() throws JAXBException, IOException, XPathExpressionException {
JAXBContext context = JAXBContext.newInstance(RootNode.class);
DOMResultSchemaOutputResolver schemaOutputResolver = new DOMResultSchemaOutputResolver();
context.generateSchema(schemaOutputResolver);
// Do your manipulations here as you want. Below is just an example!
filterXsdDocumentComplexTypes(schemaOutputResolver.getDocument(), asList("childNodeA"), true);
filterXsdDocumentElements(schemaOutputResolver.getDocument(), asList("fieldB"));
serializeXsdToFile(schemaOutputResolver.getDocument(), "xf.xsd");
}
private boolean shouldComplexTypeBeDeleted(String complexTypeName, List<String> complexTypes, boolean whitelist) {
return (whitelist && !complexTypes.contains(complexTypeName)) || (!whitelist && complexTypes.contains(complexTypeName));
}
protected void filterXsdDocumentComplexTypes(Document xsdDocument, List<String> complexTypes, boolean whitelist) throws XPathExpressionException {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList complexTypeNodes = (NodeList)xPath.evaluate("//*[local-name() = 'complexType']", xsdDocument, XPathConstants.NODESET);
for (int i = 0; i < complexTypeNodes.getLength(); i++) {
Node node = complexTypeNodes.item(i);
Node complexTypeNameNode = node.getAttributes().getNamedItem("name");
if (complexTypeNameNode != null) {
if (shouldComplexTypeBeDeleted(complexTypeNameNode.getNodeValue(), complexTypes, whitelist)) {
node.getParentNode().removeChild(node);
}
}
}
NodeList elements = (NodeList)xPath.evaluate("//*[local-name() = 'element']", xsdDocument, XPathConstants.NODESET);
for (int i = 0; i < elements.getLength(); i++) {
Node node = elements.item(i);
Node typeNameNode = node.getAttributes().getNamedItem("type");
if (typeNameNode != null) {
if (shouldComplexTypeBeDeleted(typeNameNode.getNodeValue(), complexTypes, whitelist) && !typeNameNode.getNodeValue().startsWith("xs")) {
node.getParentNode().removeChild(node);
}
}
}
}
protected void filterXsdDocumentElements(Document xsdDocument, List<String> blacklistedElements) throws XPathExpressionException {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList elements = (NodeList)xPath.evaluate("//*[local-name() = 'element']", xsdDocument, XPathConstants.NODESET);
for (int i = 0; i < elements.getLength(); i++) {
Node node = elements.item(i);
if (blacklistedElements.contains(node.getAttributes().getNamedItem("name").getNodeValue())) {
node.getParentNode().removeChild(node);
}
}
}

xslt - resolve schema in target xml

I transform one xml to other using xslt.
The point is that in target xml I need shema to be resolved.
Where link to this schema should reside? Please, provide me with right approach for that.
Is the used API enough:
import javax.xml.transform.*;
public class Main implements URIResolver{
private File root;
public static void main(String[] args) throws TransformerException, TransformerConfigurationException,
FileNotFoundException, IOException {
TransformerFactory tFactory = TransformerFactory.newInstance();
tFactory.setURIResolver(new URIResolver() {
public Source resolve(String href, String base) {
if (href.endsWith("in.xml")) {
return new StreamSource(this.getClass().getResourceAsStream("in.xml"));
} else {
return null;
}
}
});
Transformer transformer = tFactory.newTransformer(new StreamSource("rules.xsl"));
transformer.transform(new StreamSource("in.xml"), new StreamResult(new FileOutputStream("out.xml")));
System.out.println("************* The result is in out.xml *************");
#Override
public Source resolve(String href, String base) throws TransformerException {
StreamSource source = new StreamSource(getInputStream(href));
// this works with saxon7/saxon6.5.2/xalan
source.setSystemId(href);
return source;
}
protected InputStream getInputStream(String path)
{
InputStream file = null;
try
{
// load from a dir
file = new FileInputStream(new File(this.root, path));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
System.out.println("File not found");
}
return file;
}
in.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<enfinity
xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.1/core/impex-dt">..
rules.xsl:
<custom-attribute name="isPerformance" dt:dt="int">1</custom-attribute>
I got:
org.xml.sax.SAXParseException: The prefix "dt" for attribute "dt:dt" associated with an element type "custom-attribute" is not bound.
Exception in thread "main" java.lang.NullPointerException
First step is to solve the SAXParseException. This is caused because your rules.xsl file is not namespace-well-formed. You can't use the namespace prefix dt in your stylesheet unless it is declared in the stylesheet. So add xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.1/core/impex-dt" to the stylesheet.
If the file you have shown as rules.xsl is the entire file, then it's going to fail because this file is not an XSLT stylesheet.
I can't really help you with your first question, about the reference to a schema. It would help to show what output you want to produce. But you seem to have some much more basic problems to solve first.

Categories

Resources