Update 1: New Validation method throws new error, see below.
Update 2: i have checked the xml files with xml spy. No errors there.
Hope somebody see where iam wrong.
i'm currently trying to validate xml file against an xsd which includes another xsd. I don' know if my xsds or the java code is faulty. I dont have the xml/xsd files stored, i get them as a base64 string from the server. Hope somebody can help.
I get the fllowing error:
org.xml.sax.SAXParseException; lineNumber: 81; columnNumber: 104; src-resolve: Cannot resolve the name 'ServiceSpecificationSchema:ServiceIdentifier' to a(n) 'type definition' component.
-ServiceSpecificationSchema.xsd
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd" targetNamespace="http://example.org/ServiceSpecificationSchema.xsd" version="1.0" xml:lang="EN">
<include schemaLocation="ServiceBaseTypesSchema.xsd"/>
<element name="serviceSpecification" type="ServiceSpecificationSchema:ServiceSpecification">
<unique name="serviceDataModelTypeKey">
<selector xpath=".//xs:*"/>
<field xpath="#name"/>
</unique>
<keyref name="serviceDataModelReturnValueTypeKeyRef" refer="ServiceSpecificationSchema:serviceDataModelTypeKey">
<selector xpath=".//ServiceSpecificationSchema:returnValueType"/>
<field xpath="ServiceSpecificationSchema:typeReference"/>
</keyref>
<keyref name="serviceDataModelParameterTypeTypeKeyRef" refer="ServiceSpecificationSchema:serviceDataModelTypeKey">
<selector xpath=".//ServiceSpecificationSchema:parameterType"/>
<field xpath="ServiceSpecificationSchema:typeReference"/>
</keyref>
</element>
<complexType name="ServiceSpecification">
<all>
<element name="id" type="ServiceSpecificationSchema:ServiceIdentifier" minOccurs="1" maxOccurs="1"/>
.....
ServiceBaseTypeSchema:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd" targetNamespace="http://example/ServiceSpecificationSchema.xsd" version="1.0" xml:lang="EN">
...
<simpleType name="ServiceIdentifier">
<restriction base="string"/>
</simpleType>
...
</schema>
Java Validator
public void validate(String inputXml, String XSD, String XSD2)
throws SAXException, IOException {
try {
byte[] decoded = Base64.decodeBase64(XSD);
XSD = new String(decoded, "UTF-8");
byte[] decoded2 = Base64.decodeBase64(XSD2);
XSD2 = new String(decoded2, "UTF-8");
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema(new SAXSource[]
{
(new SAXSource(new InputSource(new StringReader(XSD)))),
(new SAXSource(new InputSource(new StringReader(XSD2))))
});
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(inputXml)));
} catch (SAXException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
I found another possible solution, but it still don't work. With the following method, the exeption is thrown, wenn validating the xsds against the xml. The line of the excetion depends on the used xml. In the Example on the bottom, the error is in line 2. -> Error: Cannot find the declaration of element 'ServiceSpecificationSchema:serviceSpecification'
I think: 1. My java code is faulty or 2. all the xml files are.
New Java Validator:
byte[] decoded = Base64.decodeBase64(XSD);
byte[] decoded2 = Base64.decodeBase64(XSD2);
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
InputStream impFis = new ByteArrayInputStream(decoded2);
InputStream mainFis = new ByteArrayInputStream(decoded);
Source main = new StreamSource(mainFis);
Source imp = new StreamSource(impFis);
Source[] schemaFiles = new Source[] {imp, main};
Schema schema = factory.newSchema(schemaFiles);
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(inputXml)));
Example XML file:
<?xml version="1.0" encoding="UTF-8"?>
<ServiceSpecificationSchema:serviceSpecification
xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.org/ServiceSpecificationSchema.xsd">
.....
Finally i found a solution. Thestandard method does not resolve included or imported files from the start. To resolve the included files i used the LSResourceResolver.
This works for me:
#Service
public class ResourceResolverImpl implements LSResourceResolver {
private ILoadFromSRService iLoadFromSRService;
#Autowired
public ResourceResolverImpl(ILoadFromSRService iLoadFromSRService){
this.iLoadFromSRService = iLoadFromSRService;
}
public LSInput resolveResource(String type,
String namespaceURI,
String publicId,
String systemId,
String baseURI) {
String string =iLoadFromSRService.getServiceBaseTypeSchema();
string = string.replace("\n", "").replace("\t", "");
InputStream resourceAsStream = new ByteArrayInputStream( string.getBytes());
return new LSInputImpl(publicId, systemId, resourceAsStream);
}
}
Related
I'm trying to validate an XML file against a number of different schemas (apologies for the contrived example):
a.xsd
b.xsd
c.xsd
c.xsd in particular imports b.xsd and b.xsd imports a.xsd, using:
<xs:include schemaLocation="b.xsd"/>
I'm trying to do this via Xerces in the following manner:
XMLSchemaFactory xmlSchemaFactory = new XMLSchemaFactory();
Schema schema = xmlSchemaFactory.newSchema(new StreamSource[] { new StreamSource(this.getClass().getResourceAsStream("a.xsd"), "a.xsd"),
new StreamSource(this.getClass().getResourceAsStream("b.xsd"), "b.xsd"),
new StreamSource(this.getClass().getResourceAsStream("c.xsd"), "c.xsd")});
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(xmlContent)));
but this is failing to import all three of the schemas correctly resulting in cannot resolve the name 'blah' to a(n) 'group' component.
I've validated this successfully using Python, but having real problems with Java 6.0 and Xerces 2.8.1. Can anybody suggest what's going wrong here, or an easier approach to validate my XML documents?
So just in case anybody else runs into the same issue here, I needed to load a parent schema (and implicit child schemas) from a unit test - as a resource - to validate an XML String. I used the Xerces XMLSchemFactory to do this along with the Java 6 validator.
In order to load the child schema's correctly via an include I had to write a custom resource resolver. Code can be found here:
https://code.google.com/p/xmlsanity/source/browse/src/com/arc90/xmlsanity/validation/ResourceResolver.java
To use the resolver specify it on the schema factory:
xmlSchemaFactory.setResourceResolver(new ResourceResolver());
and it will use it to resolve your resources via the classpath (in my case from src/main/resources). Any comments are welcome on this...
http://www.kdgregory.com/index.php?page=xml.parsing
section 'Multiple schemas for a single document'
My solution based on that document:
URL xsdUrlA = this.getClass().getResource("a.xsd");
URL xsdUrlB = this.getClass().getResource("b.xsd");
URL xsdUrlC = this.getClass().getResource("c.xsd");
SchemaFactory schemaFactory = schemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//---
String W3C_XSD_TOP_ELEMENT =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\">\n"
+ "<xs:include schemaLocation=\"" +xsdUrlA.getPath() +"\"/>\n"
+ "<xs:include schemaLocation=\"" +xsdUrlB.getPath() +"\"/>\n"
+ "<xs:include schemaLocation=\"" +xsdUrlC.getPath() +"\"/>\n"
+"</xs:schema>";
Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(W3C_XSD_TOP_ELEMENT), "xsdTop"));
The schema stuff in Xerces is (a) very, very pedantic, and (b) gives utterly useless error messages when it doesn't like what it finds. It's a frustrating combination.
The schema stuff in python may be a lot more forgiving, and was letting small errors in the schema go past unreported.
Now if, as you say, c.xsd includes b.xsd, and b.xsd includes a.xsd, then there's no need to load all three into the schema factory. Not only is it unnecessary, it will likely confuse Xerces and result in errors, so this may be your problem. Just pass c.xsd to the factory, and let it resolve b.xsd and a.xsd itself, which it should do relative to c.xsd.
From the xerces documentation :
http://xerces.apache.org/xerces2-j/faq-xs.html
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
...
StreamSource[] schemaDocuments = /* created by your application */;
Source instanceDocument = /* created by your application */;
SchemaFactory sf = SchemaFactory.newInstance(
"http://www.w3.org/XML/XMLSchema/v1.1");
Schema s = sf.newSchema(schemaDocuments);
Validator v = s.newValidator();
v.validate(instanceDocument);
I faced the same problem and after investigating found this solution. It works for me.
Enum to setup the different XSDs:
public enum XsdFile {
// #formatter:off
A("a.xsd"),
B("b.xsd"),
C("c.xsd");
// #formatter:on
private final String value;
private XsdFile(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
Method to validate:
public static void validateXmlAgainstManyXsds() {
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
String xmlFile;
xmlFile = "example.xml";
// Use of Enum class in order to get the different XSDs
Source[] sources = new Source[XsdFile.class.getEnumConstants().length];
for (XsdFile xsdFile : XsdFile.class.getEnumConstants()) {
sources[xsdFile.ordinal()] = new StreamSource(xsdFile.getValue());
}
try {
final Schema schema = schemaFactory.newSchema(sources);
final Validator validator = schema.newValidator();
System.out.println("Validating " + xmlFile + " against XSDs " + Arrays.toString(sources));
validator.validate(new StreamSource(new File(xmlFile)));
} catch (Exception exception) {
System.out.println("ERROR: Unable to validate " + xmlFile + " against XSDs " + Arrays.toString(sources)
+ " - " + exception);
}
System.out.println("Validation process completed.");
}
I ended up using this:
import org.apache.xerces.parsers.SAXParser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.IOException;
.
.
.
try {
SAXParser parser = new SAXParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
parser.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", "http://your_url_schema_location");
Validator handler = new Validator();
parser.setErrorHandler(handler);
parser.parse("file:///" + "/home/user/myfile.xml");
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException ex) {
e.printStackTrace();
}
class Validator extends DefaultHandler {
public boolean validationError = false;
public SAXParseException saxParseException = null;
public void error(SAXParseException exception)
throws SAXException {
validationError = true;
saxParseException = exception;
}
public void fatalError(SAXParseException exception)
throws SAXException {
validationError = true;
saxParseException = exception;
}
public void warning(SAXParseException exception)
throws SAXException {
}
}
Remember to change:
1) The parameter "http://your_url_schema_location" for you xsd file location.
2) The string "/home/user/myfile.xml" for the one pointing to your xml file.
I didn't have to set the variable: -Djavax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema=org.apache.xerces.jaxp.validation.XMLSchemaFactory
Just in case, anybody still come here to find the solution for validating xml or object against multiple XSDs, I am mentioning it here
//Using **URL** is the most important here. With URL, the relative paths are resolved for include, import inside the xsd file. Just get the parent level xsd here (not all included xsds).
URL xsdUrl = getClass().getClassLoader().getResource("my/parent/schema.xsd");
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsdUrl);
JAXBContext jaxbContext = JAXBContext.newInstance(MyClass.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema(schema);
/* If you need to validate object against xsd, uncomment this
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<MyClass> wrappedObject = objectFactory.createMyClassObject(myClassObject);
marshaller.marshal(wrappedShipmentMessage, new DefaultHandler());
*/
unmarshaller.unmarshal(getClass().getClassLoader().getResource("your/xml/file.xml"));
If all XSDs belong to the same namespace then create a new XSD and import other XSDs into it. Then in java create schema with the new XSD.
Schema schema = xmlSchemaFactory.newSchema(
new StreamSource(this.getClass().getResourceAsStream("/path/to/all_in_one.xsd"));
all_in_one.xsd :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ex="http://example.org/schema/"
targetNamespace="http://example.org/schema/"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:include schemaLocation="relative/path/to/a.xsd"></xs:include>
<xs:include schemaLocation="relative/path/to/b.xsd"></xs:include>
<xs:include schemaLocation="relative/path/to/c.xsd"></xs:include>
</xs:schema>
This question already has answers here:
XML validation failing in java with schemaLocation a local file
(2 answers)
Closed 2 years ago.
I try to load my local xsd file (import...schemaLocation="gml.xsd" but it seems nothing working because I got always same error :
org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 122; src-resolve: Cannot resolve the name 'gml:AbstractFeature' to a(n) 'element declaration' component.
config.xsd :
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:pcrs="http://cnig.gouv.fr/pcrs" xmlns:pcrs-i="http://cnig.gouv.fr/pcrs-information" targetNamespace="http://cnig.gouv.fr/pcrs" elementFormDefault="qualified" version="2.0beta2">
<import namespace="http://cnig.gouv.fr/pcrs-information" schemaLocation="CNIG_PCRS-INFO_v2.0.xsd"/>
<import namespace="http://www.opengis.net/gml/3.2" schemaLocation="gml.xsd"/>
<!--XML Schema document created by ShapeChange - http://shapechange.net/-->
<element name="AffleurantEnveloppePCRS" type="pcrs:AffleurantEnveloppePCRSType" substitutionGroup="gml:AbstractFeature">
java :
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream xsd = classloader.getResourceAsStream("gml/config.xsd");
InputStream gml = classloader.getResourceAsStream("gml/test.gml");
public boolean validateXSD() {
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(xsd));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(gml));
return true;
} catch (Exception error) {
System.out.println(error);
return false;
}
}
Since you're supplying a byte stream, the XML library has no idea where the file is located, so it cannot resolved relative paths.
As a fall-back, it likely resolved the relative paths relative to the current directory, but since the files are not there, they are not found.
Specify the XSD as a URI.
public boolean validateXSD() {
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
URL xsd = classloader.getResource("gml/config.xsd");
URL gml = classloader.getResource("gml/test.gml");
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(xsd); // Pass URL to XML library
Validator validator = schema.newValidator();
validator.validate(new StreamSource(gml.toString())); // Pass URL as a string
return true;
} catch (Exception error) {
System.out.println(error);
return false;
}
}
Advantage: You don't have to remember to close the streams, which you seemed to have forgot.
Please help!
I am trying to unmarshall the below XML STRING to a java class. The requirement is only to grab some elements and not all:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type='text/xsl' href='http://myService/rs/../xsl/searchRetrieveResponse.xsl'?>
<searchRetrieveResponse
xmlns="http://www.loc.gov/zing/srw/"
xmlns:srw5="info:srw/extension/5/restrictorSummary">
<version>1.2</version>
<numberOfRecords>1</numberOfRecords>
<records>
<record>
<recordSchema>info:srw/schema/1/CDFXML</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<institution active="true" test="true" training="false"
xmlns="info:rfa/rfaRegistry/xmlSchemas/institution"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:rfa/rfaRegistry/xmlSchemas/institution http://worldcat.org/registry/xsd/collections/Institutions/institution.xsd">
<identifier>info:rfa/Institutions/113500</identifier>
<versionID>2016-02-17T20:01:22.355Z</versionID>
<nameLocation
xmlns="info:rfa/rfaRegistry/xmlSchemas/institutions/nameLocation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:rfa/rfaRegistry/xmlSchemas/institutions/nameLocation http://worldcat.org/registry/xsd/collections/Institutions/nameLocation.xsd">
<lastUpdated>2015-09-27</lastUpdated>
<lastUpdatedTime>03:06:43</lastUpdatedTime>
<first>First Name</first>
</nameLocation>
<identifiers
xmlns="info:rfa/rfaRegistry/xmlSchemas/institutions/identifiers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:rfa/rfaRegistry/xmlSchemas/institutions/identifiers http://worldcat.org/registry/xsd/collections/Institutions/identifiers.xsd">
<lastUpdated>2016-02-17</lastUpdated>
<lastUpdatedTime>15:01:22</lastUpdatedTime>
<age>23</age>
<age>55</age>
</identifiers>
<opac available="true" intranetOnly="false"
xmlns="info:rfa/rfaRegistry/xmlSchemas/institutions/opac"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:rfa/rfaRegistry/xmlSchemas/institutions/opac http://worldcat.org/registry/xsd/collections/Institutions/opac.xsd">
<lastUpdated>2009-12-03</lastUpdated>
<lastUpdatedTime>17:43:52</lastUpdatedTime>
<url1>facebook</url1>
<url2>google</url2>
<prefix/>
</opac>
</institution>
</recordData>
<recordPosition>1</recordPosition>
</record>
</records>
</searchRetrieveResponse>
From this file I am only looking to map these tags in my java class below
<first> <age> <age> <url1> <url2>
Java class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "searchRetrieveResponse")
public class MyInfo {
#XmlElement(name = "first")
private String first;
#XmlElement(name = "age")
private List<String> age;
#XmlElement(name = "url1")
private String url1;
#XmlElement(name = "url2")
private String url2;
}
Unmarshalling implementation:
public static void main(String[] args) {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance(MyInfo.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyInfo myInfo = (MyInfo) jaxbUnmarshaller.unmarshal(
new StringReader( * * MY_XML_STRING **));
catch(JAXBException ex){
log.error("Error - ", ex);
}
}
Error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.loc.gov/zing/srw/", local:"searchRetrieveResponse"). Expected elements are <{}searchRetrieveResponse>
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:744)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:262)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1149)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:574)...
In My gradle dependencies:
jaxbApi : "javax.xml.bind:jaxb-api:2.4.0-b180830.0359",
jaxbImpl : "com.sun.xml.bind:jaxb-impl:2.4.0-b180830.0438",
jaxbCore : "org.glassfish.jaxb:jaxb-core:2.3.0.1",
And java 11 is the complier.
Add: , namespace = "http://www.loc.gov/zing/srw/"
to your #XmlRootElement:
#XmlRootElement(name = "searchRetrieveResponse", namespace = "http://www.loc.gov/zing/srw/")
...this is what the error message complains about: A mismatch in the namespace!
unexpected element (uri:"http://www.loc.gov/zing/srw/", local:"searchRetrieveResponse").
Expected elements are <{}searchRetrieveResponse>
The {} means empty ("") namespace, in this case.
If namespace omit, it defaults to "##default"...
If the value is "##default", then the XML namespace name is derived from the package of the class ( XmlSchema ). If the package is unnamed, then the XML namespace is the default empty namespace.
EDIT:
In your scenario, I would generate the classes with (built-in) xjc (command line tool ...in ${java.home}/bin)
xjc -d generated <schema>
...where gnerated will be the output folder for the classes (.java files) and <schema> can be a file URL or (structured)directory (with your (readonly) xsd(s)).
Once successfully generated, copy the content of generated into your "main source folder", check it in(, use it) and only change it, when xsd changes.
I used Jaxb for read and write from my XML File.I want update spacial element in my XML, but I don't know how can do that in my code,any body you can till me how I can do that.
That my update method
public boolean Update(Layer entity) {
try {
File file = new File(Test.PathXMl);
//read from my xml
JAXBContext jaxbContext = JAXBContext.newInstance(Project.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Project project = (Project) jaxbUnmarshaller.unmarshal(file);
// here update my XML new value but not special element
Layer layer = new Layer();
layer.setLayerName(entity.getLayerName());
layer.setOrder(entity.getOrder());
layer.setVisible(entity.isVisible());
project.getLayer().add(layer);
//write in xml file
ObjectFactory objectFactory = new ObjectFactory();
javax.xml.bind.Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(project, new FileOutputStream(Test.PathXMl));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
return false;
}
My XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://www.example.org/ProjectDataBase" name="name1">
<Layer idLayer="2">
<LayerName>a</LayerName>
<Order>2</Order>
<Visible>false</Visible>
</Layer>
<Layer idLayer="1">
<LayerName>add</LayerName>
<Order>1</Order>
<Visible>true</Visible>
</Layer>
</Project>
NOTE: For example I need change value in LayerName from a -->b but just in IdLayer="2"(In my code I can't select my element which I want update).Please any way for do that!!!!
Once you have unmarshalled the XML, you should perform the following check
// unmarshal Project
for(Layer layer : project.getLayer()) {
if (layer.getIdLayer().equals("2")) {
layer.setLayerName("b");
}
}
// marshal Project back to XML
I have XSD which describes custom schema and which imports XLink (another schema).
Import is made with the following declaration ix main XSD:
<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="xlink.xsd"/>
xlink.xsd file is actually located near the main XSD.
Then I configure builders with the following code
static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
static final String MY_SCHEMA_FILENAME = "mydir/myfile.xsd";
static final String MY_DATA_FILENAME = "mydir/myfile.xml";
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
try {
factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
factory.setAttribute(JAXP_SCHEMA_SOURCE, new File(MY_SCHEMA_FILENAME));
}
catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
try {
builder = factory.newDocumentBuilder();
}
catch(ParserConfigurationException e) {
throw new AssertionError(e);
}
when I prepare document in memory, I set attribute the following way
imageElement.setAttribute("xlink:href", mypathvariable);
I expect this will create tag which is described following way in XSD
<xs:element name="image">
<xs:complexType>
<xs:attribute ref="xlink:href" use="required"/>
</xs:complexType>
</xs:element>
While creating everything works without any errors, but while saving with code
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(MY_DATA_FILENAME));
transformer.transform(source, result);
the following error occurs:
ERROR: 'Namespace for prefix 'xlink' has not been declared.'
Where is my mistake?
Use setAttributeNS instead, something like this:
imageElement.setAttributeNS("http://www.w3.org/1999/xlink", "href", mypathvariable);
If you want to stick with:
imageElement.setAttribute("xlink:href", mypathvariable);
Then make sure you have this defined (typically on the root element), on some element that provides scope to where your attribute is being added:
someElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
The above also shows how to control a prefix in general.