I am new to XML. I am trying to define key value pairs in XML so that this file can be used as configuration file for my project. I am getting errors while I am loading this xml file in java. Please let me know how to fix this issue.
XML file (data.xml):
<?xml version="1.0"?>
<object>
<field name="property1" value="1">
<field name="property2" value="2">
<field name="property3" value="3">
<field name="property4" value="4">
</object>
</xml>
Java Code:
import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;
public class PreferencesExample {
public static void main(String args[]) throws FileNotFoundException {
Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
// Load file object
File fileObj = new File("data.xml");
try {
FileInputStream fis = new FileInputStream(fileObj);
ps.importPreferences(fis);
System.out.println("Prefereces:"+ps);
System.out.println("Get property1:"+ps.getInt("property1",10));
} catch (Exception err) {
err.printStackTrace();
}
}
}
I got below error while I load this xml in java.
>
java.util.prefs.InvalidPreferencesFormatException: org.xml.sax.SAXParseException;
lineNumber: 2; columnNumber: 9; Document root element "object", must match DOCTYPE root "null".
at java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:216)
at java.util.prefs.Preferences.importPreferences(Preferences.java:1259)
What would be possible root cause? I am suspecting XML file format but I don't have expertise in XML
Your xml file should be in the below format
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
<map />
<node name="mypack">
<map />
<node name="test">
<map>
<entry key="property1" value="80" />
<entry key="property2" value="Red" />
</map>
</node>
</node>
</node>
</root>
</preferences>
and the node names are the package name of the class PreferencesExample. In this example, it is com/mypack/test.
this link might be helpful for java preferences
Related
I am seeing a weird behaviour of w3c dom library for Java. For my XML which is formatted, I ran document.getElementsByTagName().getItem(0).getChildNodes() for fetching one of the tags' child nodes. Below is how my tag looks like:
<References>
<Reference Name="a" Value="1"/>
<Reference Name="b" Value="2"/>
<Reference Name="c" Value="3"/>
<Reference Name="d" Value="4"/>
<Reference Name="e" Value="5"/>
<Reference Name="f" Value="6"/>
<Reference Name="g" Value="7"/>
<Reference Name="h" Value="8"/>
<Reference Name="i" Value="9"/>
<Reference Name="j" Value="10"/>
<Reference Name="k" Value="11"/>
<Reference Name="l" Value="12"/>
</References>
Below is my code:
NodeList nodeList = document.getElementsByTagName("References").item(0).getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
NamedNodeMap currentItemAttributes = nodeList.item(i).getAttributes();
String currentItemName = currentItemAttributes.getNamedItem("Name").getNodeValue();
name=currentItemName;
}
Here, I get null value for every alternate node as explained below:
nodeList.item(0).getAttributes() returns null
nodeList.item(1).getAttributes().getNamedItem("Name").getNodeValue() returns a
nodeList.item(2).getAttributes() returns null
nodeList.item(3).getAttributes().getNamedItem("Name").getNodeValue() returns b
and so on.
Interestingly, if I minify my xml file to a single line and remove all the extra spaces, it works fine and I do not get alternate null values.
If anyone can give me a solution to this, it'd be a great help.
It's because the getChildNodes() is getting all the NODES.
Try
document.getElementsByTagName("References").item(0).getElementsByTagName("Reference");
Or you can check each node for type (Element) and name (Reference) and handle it then.
I'm trying to generate the following xml file which has 2 fields as Header and the Repeating section "rec" node :
<?xml version="1.0" encoding="UTF-8"?>
<transaction>
<createDate>20160708</createDate>
<dlrCode>100<dlrCode/>
<rec>
<processDate>20190108</processDate>
<srcID/>10<srcID/>
</rec>
<rec>
<processDate>20190108</processDate>
<srcID/>11<srcID/>
</rec>
<rec>
<processDate>20190108</processDate>
<srcID/>12<srcID/>
</rec>
</transaction>
This is the mapping file which I created:
<?xml version="1.0" encoding="UTF-8"?>
<beanio xmlns="http://www.beanio.org/2012/03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">
<stream name="dist" format="xml" xmlName="transaction" >
<record name="HeaderRecord" class="com.myPackage.HeaderRecord" minOccurs="1" maxOccurs="1" order="1" >
<field name="createDate" format="yyyyMMdd" />
<field name="dlrCode" />
</record>
<record name="DisRecord" class="com.myPackage.Record" minOccurs="0" maxOccurs="unbounded" xmlName="rec" order="2">
<field name="processDate" format="yyyyMMdd"/>
<field name="srcID"/>
</record>
</stream>
</beanio>
But the problem is, it generates the header fields inside the HeaderRecord node like this:
<?xml version="1.0" encoding="UTF-8"?>
<transaction>
<HeaderRecord>
<createDate>20160708</createDate>
<dlrCode>100<dlrCode/>
</HeaderRecord>
<rec>
<processDate>20190108</processDate>
<srcID/>10<srcID/>
</rec>
<rec>
<processDate>20190108</processDate>
<srcID/>11<srcID/>
</rec>
<rec>
<processDate>20190108</processDate>
<srcID/>12<srcID/>
</rec>
</transaction>
Is there something misconfigured in the mapping file? How to achieve the desired output?
By using the xmlType="none" attribute you can control if an xml element should be produced or not. The xmlName is by default equal to the record name when you don't specify a xmlName attribute, see here. A record will always be mapped to an xml element and with the use of segments, you might be able to get the desired output.
Try this mapping file:
<stream name="dist" format="xml" xmlType="none" >
<record name="HeaderRecord" class="com.mypackage.HeaderRecord" minOccurs="1" maxOccurs="1" xmlName="transaction">
<segment name="dummy" xmlType="none">
<field name="createDate" format="yyyyMMdd" />
<field name="dlrCode" />
</segment>
</record>
I don't think it is 100% what you are looking for though.
Today I am using Jpmml in order to load pmml models in my code. but the'evaluate' method takes long time.
Here is the working code today :
String modelPath = "....";
ModelEvaluatorFactory factory = ModelEvaluatorFactory.newInstance();
InputStream in = new ByteArrayInputStream(modelPath.getBytes("UTF-8"));
PMML pmmlModel = JAXBUtil.unmarshalPMML(new StreamSource(in));
ModelEvaluator<?> evaluator = factory.newModelManager(pmmlModel);
List<FieldName> activeFields = evaluator.getActiveFields();
Map<FieldName, FieldValue> defaultFeatures = new HashMap<>();
//after filling the 'defaultFeatures' the line below takes long time
Map<FieldName, ?> results = evaluator.evaluate(defaultFeatures);
PMML example :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_2" version="4.2">
<Header>
<Application name="JPMML-SkLearn" version="1.0-SNAPSHOT"/>
<Timestamp>2017-01-22T14:18:05Z</Timestamp>
</Header>
<DataDictionary>
<DataField name="GENDER" optype="categorical" dataType="string">
<Value value="0"/>
<Value value="1"/>
</DataField>
<DataField name="1GA_" optype="continuous" dataType="double"/>
//67000 rows of datafield
</DataDictionary>
<TransformationDictionary>
<DefineFunction name="logit" optype="continuous" dataType="double">
<ParameterField name="value" optype="continuous" dataType="double"/>
<Apply function="/">
<Constant dataType="double">1</Constant>
<Apply function="+">
<Constant dataType="double">1</Constant>
<Apply function="exp">
<Apply function="*">
<Constant dataType="double">-1</Constant>
<FieldRef field="value"/>
</Apply>
</Apply>
</Apply>
</Apply>
</DefineFunction>
</TransformationDictionary>
<MiningModel functionName="classification">
<MiningSchema>
<MiningField name="GENDER" usageType="target"/>
<MiningField name="1GA_"/>
//67000 rows of MiningField
</MiningSchema>
<Output>
<OutputField name="probability_0" feature="probability" value="0"/>
<OutputField name="probability_1" feature="probability" value="1"/>
</Output>
<LocalTransformations>
<DerivedField name="x1" optype="continuous" dataType="double">
<FieldRef field="1GA_"/>
</DerivedField>
//100000 rows
</LocalTransformations>
<Segmentation multipleModelMethod="modelChain">
<Segment id="1">
<True/>
<RegressionModel functionName="regression">
<MiningSchema>
<MiningField name="1GA_"/>
</MiningSchema>
<Output>
<OutputField name="decisionFunction_1" feature="predictedValue"/>
<OutputField name="logitDecisionFunction_1" optype="continuous" dataType="double" feature="transformedValue">
<Apply function="logit">
<FieldRef field="decisionFunction_1"/>
</Apply>
</OutputField>
</Output>
<RegressionTable intercept="-5.303370169392045">
<NumericPredictor name="x1" coefficient="0.18476274186559316"/>
//100000 rows of NumericPredictor
</RegressionTable>
</RegressionModel>
</Segment>
<Segment id="2">
<True/>
<RegressionModel functionName="regression">
<MiningSchema>
<MiningField name="logitDecisionFunction_1"/>
</MiningSchema>
<Output>
<OutputField name="logitDecisionFunction_0"
feature="predictedValue"/>
</Output>
<RegressionTable intercept="1.0">
<NumericPredictor name="logitDecisionFunction_1"
coefficient="-1.0"/>
</RegressionTable>
</RegressionModel>
</Segment>
<Segment id="3">
<True/>
<RegressionModel functionName="classification">
<MiningSchema>
<MiningField name="GENDER" usageType="target"/>
<MiningField name="logitDecisionFunction_1"/>
<MiningField name="logitDecisionFunction_0"/>
</MiningSchema>
<RegressionTable intercept="0.0" targetCategory="1">
<NumericPredictor name="logitDecisionFunction_1"
coefficient="1.0"/>
</RegressionTable>
<RegressionTable intercept="0.0" targetCategory="0">
<NumericPredictor name="logitDecisionFunction_0"
coefficient="1.0"/>
</RegressionTable>
</RegressionModel>
</Segment>
</Segmentation>
</MiningModel>
</PMML>
There is a thought of trying to use MLlib instead of Jpmml.
Any ideas?
Thanks
What do you mean by "load"? Is it "parse PMML document into an in-memory data structure" or "execute PMML document"?
Your code appears to be aim for the latter. But it will definitely fail, because the JAXBUtil#unmarshalPMML(Source) method is invoked with a byte array, which doesn't contain a valid PMML document (no XML parser will accept "....".getBytes("UTF-8")).
Also, what do you mean by "takes long time"? The JAXB framework has one-time initialization cost of around ~1 second. After that it can unmarshal ~200 to 500 MB (that's megabytes) of PMML content per second. How much more do you need?
My Java application tries to get information from a webservice. The XML request needs to have the namespace specified in the XML root element (class name), but the namespace of the tags (class fields) need to be empty (null), otherwise the webservice rejects the request.
I have to use Spring 3.0 and Spring WS 2.0 with CastorMarshaller (currently using Castor version 1.3.1) to marshall/unmarshall my Java objects into/from XML.
Please note the __PREFIX__ and __NAMESPACE__ locations in following code snippets.
Desired marshalled output
(i.e. the desired generated SOAP request)
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
<soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<__PREFIX__:className xmlns:__PREFIX__="__NAMESPACE__">
<fieldName>fieldValue</fieldName>
</__PREFIX__:className>
</soap-env:Body>
</soap-env:Envelope>
Currently marshalled output (i.e. the generated SOAP request)
Not adding the namespace
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
<soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<className>
<fieldName>fieldValue</fieldName>
</className>
</soap-env:Body>
</soap-env:Envelope>
or adding the namespace to all elements
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
<soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<__PREFIX__:className xmlns:__PREFIX__="__NAMESPACE__">
<__PREFIX__:fieldName xmlns:__PREFIX__="__NAMESPACE__">fieldValue</__PREFIX__:fieldName>
</__PREFIX__:className>
</soap-env:Body>
</soap-env:Envelope>
which are both rejected by the webservice.
My configuration
CastorMarshaller bean in applicationContext.xml
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation" value="classpath:castor-mapping.xml" />
<property name="ignoreExtraAttributes" value="true" />
<property name="ignoreExtraElements" value="true" />
<property name="namespaceMappings">
<map>
<entry key="__PREFIX__" value="__NAMESPACE__" />
</map>
</property>
</bean>
Castor Mapping file castor-mapping.xml
Not adding the namespace (namespace specified in the castorMarshaller bean through namespaceMappings should be added to the root)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd">
<mapping>
<class name="some.package.ClassName">
<map-to xml="className">
<field name="fieldName" type="string">
<bind-xml name="fieldName" node="element" />
</field>
</class>
</mapping>
or adding the namespace to all elements
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd">
<mapping>
<class name="some.package.ClassName">
<map-to xml="className" ns-uri="__NAMESPACE__" ns-prefix="__PREFIX__">
<field name="fieldName" type="string">
<bind-xml name="fieldName" node="element" />
</field>
</class>
</mapping>
Since I am facing the same problem, a solution that I am considering is the following:
Create a interceptor extending EndpointInterceptorAdapter
Override handleResponse method
Modify to soap message by directly access or using a transformer
public class MyEndpointInterceptorAdapter extends
EndpointInterceptorAdapter{
#Override
public boolean handleResponse(MessageContext msgContext, Object endpoint) throws IOException {
WebServiceMessage responseMsg = msgContext.getResponse();
SoapMessage soapMsg = (SoapMessage) responseMsg;
if(soapMsg!=null){
SoapEnvelope soapEnvelope=soapMsg.getEnvelope();
if(soapEnvelope!=null){
SoapBody soapbody=soapEnvelope.getBody();
if(soapbody!=null){
Source bodySource=soapbody.getSource();
if(bodySource instanceof DOMSource){
DOMSource bodyDomSource=(DOMSource)bodySource;
Node bodyNode=bodyDomSource.getNode();
if(bodyNode!=null){
NodeList bodyNodeList=bodyNode.getChildNodes();
if(bodyNodeList.getLength()!=0){
Element root=(Element)bodyNodeList.item(0);
root.setAttribute("xmlns:ns", "YourURI");
root.setPrefix("ns");
}
}
}
}
}
}
return true;
}
}
I have a JiBX binding file that specifies namespaces. However, I want to turn off namespace validation so that even an XML message with invalid namespace could be unmarshalled.
I have a binding file like the following:
<binding name="test_binding">
<namespace prefix="soapenv" uri="http://www.w3.org/2003/05/soap-envelope" />
<!-- Envelope -->
<mapping name="Envelope" ns="http://www.w3.org/2003/05/soap-envelope"
class="com.test.data.Envelope">
<structure get-method="getHeader" set-method="setHeader"
ns="http://www.w3.org/2003/05/soap-envelope" usage="optional" />
<structure get-method="getBody" set-method="setBody"
ns="http://www.w3.org/2003/05/soap-envelope" usage="optional" />
</mapping>
...
I pass the following message to JiBX unmarshaller (with different namespace for Envelope element):
<?xml version="1.0" encoding="UTF-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope">
<soapenv:Header>
<MyElement>
....
The following shows the error message when JiBX unmarshalls the message:
[Time:2011-10-04 17:39:29,802][Level:FATAL]org.jibx.runtime.JiBXException: No unmarshaller for element "{http://schemas.xmlsoap.org/soap/envelope}Envelope" (line 2, col 76)
...
Is there a way to disable namespace validation in JiBX? Thanks.