forked from int28h/JavaTasks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxmldoc.java
More file actions
209 lines (196 loc) · 11.1 KB
/
xmldoc.java
File metadata and controls
209 lines (196 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//Второй тест (пример 2 в описании задания ниже) данное решение не проходит.
/**
* Вам дан XML-документ в следующем формате:
* 1) корневым элементом документа является элемент с именем 'projects';
* 2) элемент 'projects' содержит один или несколько элементов 'project'
* с единственным атрибутом 'name';
* 3) каждый элемент 'project' содержит один или несколько пустых элементов
* 'member' с атрибутами 'role' и 'name'.
*
* Каждое значение атрибута 'name' элемента 'project' —
* это непустая последовательность из строчных латинских букв и символа
* 'дефис' (он же 'минус').
*
* Значение атрибута 'role' элемента 'member' — это также непустая
* последовательность из строчных латинских букв и символа 'дефис'
* (он же 'минус').
*
* Значение атрибута 'name' элемента 'member' — это также непустая
* последовательность из строчных и заглавных латинских букв и пробелов.
* Значение этого атрибута не может начинаться или заканчиваться пробелом.
* Других атрибутов, кроме тех, что описаны выше, у элементов нет.
*
* Необходимо преобразовать этот документ в следующий вид:
* 1) корневым элементом результата должен быть элемент с именем 'members';
* 2) элемент 'members' содержит один или несколько элементов 'member'
* с единственным атрибутом 'name';
* 3) каждый элемент 'role' содержит один или несколько пустых элементов
* 'role' с атрибутами 'project' и 'name'.
*
* Для дополнительных разъяснений изучите пример входных и выходных данных.
* Учтите, что при сравнении значений атрибутов регистр букв имеет значение.
*
* Входные данные
* Входные данные состоят из некоторого количества строк, образующих
* XML-документ в описанном выше формате. Все элементы 'project'
* имеют уникальные значения атрибутов 'name'. Каждый элемент
* находится на отдельной строке. Строки с открывающим и закрывающим
* тегами элемента 'projects' не содержат начальных пробелов,
* в начале строк с тегами элементов 'project' ровно четыре пробела,
* в начале строк с тегами элементов 'member' — ровно восемь пробелов.
* Строки не содержат концевых пробелов. Атрибуты внутри элементов
* разделены единичными пробелами. У любых двух элементов 'member'
* внутри одного и того же элемента 'project' различаются
* либо значения атрибута 'role', либо значения атрибута 'name',
* либо и те, и другие одновременно.
*
* Выходные данные
* Выведите документ в требуемом формате. Строго соблюдайте формат,
* показанный в примере выходных данных. Атрибуты элемента 'role'
* должны следовать в следующем порядке: сначала 'name', затем 'project'.
* Элементы 'member' должны следовать в лексикографическом порядке
* значений атрибутов 'name'. В каждом элементе 'member' элементы
* 'role' должны следовать в лексикографическом порядке значений
* атрибутов 'project', а при равенстве — в лексикографическом порядке
* значений атрибутов 'name'.
*
* Все лексикографические сравнения осуществляйте с учетом регистра
* символов. Например, строка 'Ba' лексикографически меньше строки
* 'aa'.
*
* ========= Пример 1 =========
* input
* <projects>
* <project name="xml">
* <member role="developer" name="Fedya"/>
* <member role="manager" name="Ivan"/>
* <member role="manager" name="Fedya"/>
* </project>
* </projects>
*
* output
* <members>
* <member name="Fedya">
* <role name="developer" project="xml"/>
* <role name="manager" project="xml"/>
* </member>
* <member name="Ivan">
* <role name="manager" project="xml"/>
* </member>
* </members>
*
*
* ========= Пример 2 =========
* input
* <projects>
* <project name="xml">
* <member role="developer" name="fedya"/>
* <member role="manager" name="Ivan"/>
* </project>
* <project name="rpc">
* <member role="developer" name="fedya"/>
* </project>
* </projects>
*
* output
* <members>
* <member name="Ivan">
* <role name="manager" project="xml"/>
* </member>
* <member name="fedya">
* <role name="developer" project="rpc"/>
* <role name="developer" project="xml"/>
* </member>
* </members>
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.Node;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Main {
private static Document stringToDocument(String xml) {
try {
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
} catch (SAXException | IOException | ParserConfigurationException e) {
e.printStackTrace();
}
return null;
}
private static String toStringFormat(int indent, Document document) {
try {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xPath.evaluate("//text()[normalize-space()='']", document,XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
org.w3c.dom.Node node = nodeList.item(i);
node.getParentNode().removeChild(node);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", indent);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter stringWriter = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
return stringWriter.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws TransformerException, ParserConfigurationException, SAXException, IOException {
DocumentBuilder inDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document inDocument = inDocumentBuilder.parse("input.xml");
Document outDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element outMembers = outDocument.createElement("members");
outDocument.appendChild(outMembers);
Element inRoot = inDocument.getDocumentElement();
NodeList inProjects = inRoot.getChildNodes(); //projects
for (int i = 0; i < inProjects.getLength(); i++) {
org.w3c.dom.Node inProject = inProjects.item(i);
if (inProject.getNodeType() != Node.TEXT_NODE) {
NodeList inMembers = inProject.getChildNodes(); //members
for(int j = 0; j < inMembers.getLength(); j++) {
org.w3c.dom.Node inMember = inMembers.item(j);
if (inMember.getNodeType() != Node.TEXT_NODE) {
System.out.println(inMember.getNodeName() + " " + inMember.getAttributes().getNamedItem("role") + " " + inMember.getAttributes().getNamedItem("name"));
Element outMember = outDocument.createElement("member");
outMembers.appendChild(outMember);
Attr outMemberName = outDocument.createAttribute("name");
outMemberName.setTextContent(inMember.getAttributes().getNamedItem("name").getNodeValue());
outMember.setAttributeNode(outMemberName);
Element outRole = outDocument.createElement("role");
outMember.appendChild(outRole);
Attr outRoleName = outDocument.createAttribute("name");
outRoleName.setTextContent(inMember.getAttributes().getNamedItem("role").getNodeValue());
outRole.setAttributeNode(outRoleName);
Attr outProjectName = outDocument.createAttribute("project");
outProjectName.setTextContent(inProject.getAttributes().getNamedItem("name").getNodeValue());
outRole.setAttributeNode(outProjectName);
}
}
}
}
String xmlString = new String(toStringFormat(4, outDocument));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(stringToDocument(xmlString)), new StreamResult("output.xml"));
}
}