Author: Bartosz Wieczorek

xsd schema – repeating elements via unbouned choice and sequence

For the schema below with choice:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
    <xs:element name="MyRootElement">
        <xs:complexType>

	    <!-- allow either (zero or more of A) or (only exactly single B) -->	
            <xs:choice>
                <xs:element name="A" maxOccurs="unbounded"/>
                <xs:element name="B" />
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>

Screen Shot 2017-08-07 at 13.33.10

we get valid xmls:
– no children

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
</MyRootElement>

– zero or more A element(s)

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <A/>
</MyRootElement>

– exactly one B element

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <B/>
</MyRootElement>

However, combination of A and B is not possible:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <B/>
</MyRootElement>

as we get

Invalid content was found starting with element 'B'. One of '{"http://www.bawi.com/schema":A}' is expected.

and also not valid xml:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <B/>
  <A></A>
</MyRootElement>

due to

Invalid content was found starting with element 'A'. No child element is expected at this point.

In order to get xml with many A elements and single B we would define a sequence:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
    <xs:element name="MyRootElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="A" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="B" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Screen Shot 2017-08-07 at 13.47.48

so that the xml below is valid:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <B/>
</MyRootElement>

For validation I have used the following code:

import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
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;
import java.io.File;
import java.io.IOException;

public class MyValidator {
    public static void main(String[] args) throws SAXException, IOException {
        File schemaFile = new File("schema.xsd");
        Source xmlFile = new StreamSource("generated.xml");
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(schemaFile);
        Validator validator = schema.newValidator();
        validator.validate(xmlFile);
        System.out.println(xmlFile.getSystemId() + " is valid");
    }
}

xsd schema declaring xml only with attributes

For schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
  <xs:element name="MyRootElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MyElement">
          <xs:complexType>
            <xs:attribute name="myAttribute"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Screen Shot 2017-07-27 at 22.06.15
we have valid xml:

<?xml version="1.0" encoding="UTF-8"?>
<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <MyElement myAttribute="anyType"/>
</MyRootElement>

but when we add text body (e.g. ‘aaa’) to the xml:

<?xml version="1.0" encoding="UTF-8"?>
<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <MyElement myAttribute="anyType">aaa</MyElement>
</MyRootElement>

then we get validation error:

lineNumber: 3; columnNumber: 51; cvc-complex-type.2.1: Element 'MyElement' must have no character or element information item [children], because the type's content type is empty.

In order to fix it we need to add simepleContent and extension to the schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
  <xs:element name="MyRootElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MyElement">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="myAttribute"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Then both xml above with be valid.
Note text-like information in the MyElement icon:
Screen Shot 2017-07-27 at 22.19.43

Empty elements such as

<MyElement/>

is allowed when schema defines it as

<xs:element name="MyElement"/>

or

<xs:element name="MyElement" type="xs:string"/>

. However, when we change schema to int type such as

<xs:element name="MyElement" type="xs:int"/>

then we get validation error:

lineNumber: 3; columnNumber: 15; cvc-datatype-valid.1.2.1: '' is not a valid value for 'integer'.

XSD schema validation of XML

Note the schema and the generated valid xml below (demonstrating different xsd schema syntax features):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
	<xs:element name="MyRootElement">
		<xs:annotation>
			<xs:documentation>Comment describing your root element</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:sequence>
				<xs:element name="MySubElement"/>
				<xs:element name="MySubElementString" type="xs:string"/>
				
				<!-- by default elements are required -->
				<xs:element name="MySubElementOptional" minOccurs="0"/>

				<xs:element name="MySubElementRequiring3CharString">
					<xs:simpleType>
					
						<!-- restriction needs to have base type -->
						<xs:restriction base="xs:string">
							<xs:length value="3"/>
						</xs:restriction>
					</xs:simpleType>
				</xs:element>
				
				<xs:element name="MySubElementDisallowingText">
					<xs:complexType>
					</xs:complexType>
				</xs:element>
				
				<xs:element name="MySubElementWithOptionalAttrAndOptionalText" type="MySubElementWithOptionalAttrAndOptionalText" />

			</xs:sequence>
			
			<!-- attribute needs to be below sequence -->
			
			<xs:attribute name="myAttribute" type="xs:integer"/>
			
			<!-- by default attributes are optional -->
			<xs:attribute name="myRequiredAttribute" type="xs:integer" use="required"/>
			
		</xs:complexType>
	</xs:element>
	
	<xs:complexType name="MySubElementWithOptionalAttrAndOptionalText">
		<xs:simpleContent>
			<xs:extension base="xs:string">
				<xs:attribute name="myIntegerAttribute" />
			</xs:extension>
		</xs:simpleContent>
	</xs:complexType>
</xs:schema>

Here is a sample xml (valid to the schema above)

<?xml version="1.0" encoding="UTF-8"?>
<MyRootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" myAttribute="0" myRequiredAttribute="0" xsi:noNamespaceSchemaLocation="my-schema.xsd">
	<MySubElement>text</MySubElement> <!-- can be replaced with: <MySubElement /> -->
	<MySubElementString>String</MySubElementString> <!-- can be replaced with: <MySubElementString /> -->
	<MySubElementOptional>text</MySubElementOptional> <!-- can be completely removed -->
	<MySubElementRequiring3CharString>aaa</MySubElementRequiring3CharString>
	<MySubElementDisallowingText/>
	<MySubElementWithOptionalAttrAndOptionalText myIntegerAttribute="text">String</MySubElementWithOptionalAttrAndOptionalText>
	<!-- can be replaced with: 	<MySubElementWithOptionalAttrAndOptionalText /> -->
</MyRootElement>

my-schema.xsd

My Mac OSX custom Intellij shortcuts

Navigate: class cmd O, additional ctrl shift T
Navigate file: cmd shift O, added ctrl shift R (removed run context configuration)
Navigate declaration, cmd B, added F3 (removed toggle bookmark)

Find usages: alt F7, added ctrl + shift + G (removed: unselect occurrences)

Find: cmd +F, added ctrl+ F (removed: right in editor actions)
Navigate File structure: cmd + F12, added ctrl + O (removed: override methods)

Refactor this: ctrl +T , added alt + shift + T (removed: switch task)
Rename: shift + F6, added alt + shift + R (removed: rerun tests)
Extract variable: alt+cmd+V, added alt + shift + L
Extract method: alt+cmd + M, added alt + shift + M
Duplicate line: added: alt+shift+D (removed cmd+D)
Hide all tool windows: shift + cmd + F12, added ctrl + M (removed: move caret to matching brace and commit message history)
Preferences: cmd + , added ctrl + alt + s
Show intention actions: alt + enter, added ctrl + 1 (Remove Go to bookmark 1)
Next highlighted error: F2, added ctrl+ . (removed: Choose lookup item and insert dot), added alt + .
Previous highlighted error: shift + F2, added ctrl+ , added alt + .
Reformat code: alt + cmd + L, added: ctrl + shift + F
Inline: added: alt + shift + I
Inline: alt + cmd + N, added alt + shift + I (removed: inspect code with editor settings)
Source code generate: cmd + N, ctrl + Enter, additionally: alt + shift + S
Extract field: alt + cmd + F, additionally alt + shift + F(removed: add to favorites)
Extract constant: alt + cmd + C, additionally: alt + shift + C (removed: recent changes)
**Extend/shrink selection: original: alt + up arrow/alt + down arrow changed to: alt + shift + arrow Up/Down, added additionally ctrl +W / ctrl + shift + W
Find in path: shift + cmd + F, added additionally: ctrl + alt + shift + F
Replace in path: shift + cmd + R, added additionally: ctrl + alt + shift + R
**Move line up: original: alt + shift + arrow Up/Down changed to: alt + arrow Up/Down
Organize imports: ctrl + alt + O, additionally: ctrl + shift + O, alt+shift+O
Navigate to Test/Junit (junit) added: ctrl + shift + J (removed: join lines), ctrl+shift+alt+T
Join lines: added: alt+shift+J
Navigate type declaration: shift + cmd + B (removed shift + ctrl +B), added: shift + ctrl + D
Navigate declaration: added F3
Navigate Super method: added: ctrl + shift + U or added: ctrl + shift + M
Navigate bookmark show: added shift + ctrl + B, added alt + shift + B, S
Bookmark add: added ctrl + B, added alt+ shift +B, A
Navigate bookmark menu: added ctrl + shift + alt + B, added alt+ shift +B, B (removed navigate type declaration)
Complete statement: ctrl + shift + Enter
Navigate to last edit location: ctrl + shift + E
Navigate line number: ctrl + shift + L

** Rename: alt + shift + R (removed: rerun tests)

** Run/Debug context configuration original: run context configuration alt + shift + R,(removed: run/debug in main menu)

ctrl+R/D – run/debug selected class in editor
ctrl+alt+R/D – run selected class in run/debug menu
ctrl+alt+cmd+R/D – serun/debug from menu

Added cmd+0, alt+0 terminal

Existing:
cmd + shift + T: navigate/create test
ctrl + Enter -> accept highlighted button in popup

VCS
Update: added cmd + U, added ctrl + U or added alt + shift + V, U
Diff: existing cmd + D (compare with local in vcs view)
Compare with same repository version: cmd+shift+D
Compare with local version: alt+shift+V, D
Compare with latest repo version: alt+shift+V, Shift+D

Prev/next difference: added ctrl + alt + ,/.
Push: existing alt + shift + K, or added: alt + P, or added: alt + shift + V, P
Revert: added alt + shift + V, R or added alt + R
History: added alt + H or added: alt + shift + H

Existing: View Parameter Info: cmd + P, added ctrl + P

Run: alt + shift + X, R
Run…: alt + shift + X, Shift + R
Debug: alt + shift + X, D
Debug…: alt + shift + X, Shift + D
Rerun tests: alt + shift + X, T
Rerun failed tests: alt + shift + X, Shift + T or alt + shift + X, F

Quick documentation: ctrl + Q
Navigate back/forward: added ctrl+alt+left/right arrow, added: alt+cmd+left/right arrow
Navigate Last edit location added: ctrl+shift+L
Navigate to line: cmd + L or added ctrl + L
Navigate bookmark: added ctrl + shift + B
Navigate to recently edited files: cmd+shift + E, ctrl+shift+E
Navigate to recent files: cmd+E, ctrl+E

Highlight usages in file: ctrl + F, ctrl + G

Generate source: added alt + shift + G
Find by action: added ctrl + shift + A
Ctrl + N added: new (Java, Scala)

Project Defaults -> Project Structure -> search sdk

Scala
Preferences-> Languages and Frameworks/Scala -> Show type info on mouse hover
Alt+Enter when cursor on valu/method -> Add type annotation to value definition
run scala console: cmd+shift+S

Java 8 Lambda returning lambda part 2

        Function<Integer, Function<Integer, Integer>> f = i1 -> i2 -> i1 - i2;
        List<Integer> ints = Arrays.asList(1, 2, 3);
        Integer res = 0;
        for (int ii = ints.size() - 1; ii >= 0; ii--) {
            Integer t = ints.get(ii); // 3 // 2 // 1
            Function<Integer, Integer> ff = f.apply(t); // i2 -> 3 - i2 // i2 -> 2 - i2 // i2 -> 1 - i2
            res = ff.apply(res); // 3 - 0 = 3 // 2 - 3 = -1 // 1 - -1 = 2
            System.out.println("intermediate res=" + res);
        }
        System.out.println("final res=" + res); // 2

Output:

intermediate res=3
intermediate res=-1
intermediate res=2
final res=2