Skip to content

Commit

Permalink
Merge pull request #44 from aoliaoaoaojiao/master
Browse files Browse the repository at this point in the history
fix json to xml duplicate key disappears
  • Loading branch information
ZhouYixun authored Nov 16, 2022
2 parents 35b4736 + 2025707 commit 4fa4e8d
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 132 deletions.
5 changes: 0 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.github.javadev</groupId>
<artifactId>underscore</artifactId>
<version>1.77</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*/
package org.cloud.sonic.driver.poco.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.underscore.U;
import org.cloud.sonic.driver.common.models.WindowSize;
import org.cloud.sonic.driver.common.tool.Logger;
import org.cloud.sonic.driver.common.tool.SonicRespException;
Expand Down Expand Up @@ -108,9 +108,8 @@ public String pageSourceForJsonString() throws SonicRespException {
@Override
public Element pageSourceForXmlElement() throws SonicRespException {
pageSourceForJsonString();
String pocoJson = "{\"Root\"" + source.substring("{\"result\"".length());
Element rootXmlElement = Jsoup.parse(pocoJsonToXml.jsonToXml(pocoJson, U.Mode.FORCE_ATTRIBUTE_USAGE,
"result"), "", Parser.xmlParser());
// String pocoJson = "{\"Root\"" + source.substring("{\"result\"".length());
Element rootXmlElement = Jsoup.parse(pocoJsonToXml.jsonObjToXml(JSON.parseObject(source).getJSONObject("result")),"", Parser.xmlParser());

rootNode.updateVersion(rootXmlElement);

Expand All @@ -120,7 +119,7 @@ public Element pageSourceForXmlElement() throws SonicRespException {
@Override
public PocoElement findElement(String selector, String expression) throws SonicRespException {
List<PocoElement> pocoElements = findElements(selector, expression);
return pocoElements.size() <= 0 ? null : pocoElements.get(0);
return pocoElements.get(0);
}

@Override
Expand All @@ -140,18 +139,22 @@ public List<PocoElement> findElements(String selector, String expression) throws
newExpress += ("/*" + parseAttr(step));
if (step.endsWith("]") && step.contains("[")) {
int index = Integer.parseInt(step.substring(step.indexOf("[") + 1, step.indexOf("]")));
newExpress += ("[" + index + 1 + "]");
newExpress += ("[" + (index + 1) + "]");
}
}
}
expression = newExpress;
xmlNodes = rootNode.getXmlElement().selectXpath(newExpress);
break;
case "xpath":
xmlNodes = rootNode.getXmlElement().selectXpath(expression);
break;
case "cssSelector":
xmlNodes = rootNode.getXmlElement().select(expression);
break;
}
if (xmlNodes == null ||xmlNodes.isEmpty()){
throw new SonicRespException(String.format("poco element not found for selector:%s, value:%s",selector,expression));
}
List<PocoElement> result = new ArrayList<>();
for (Element node : xmlNodes) {
PocoElement pocoElement = new PocoElement(rootNode, node);
Expand Down
189 changes: 73 additions & 116 deletions src/main/java/org/cloud/sonic/driver/poco/util/pocoJsonToXml.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,138 +16,95 @@
*/
package org.cloud.sonic.driver.poco.util;

import com.github.underscore.Json;
import com.github.underscore.U;
import com.github.underscore.Xml;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class pocoJsonToXml extends U {
private static final String ROOT = "root";

public pocoJsonToXml(Iterable iterable) {
super(iterable);
public class pocoJsonToXml {
/**
* convert json to xml
*
* @param jo JSONObject
*
* @return xml
*/
public static String jsonObjToXml(JSONObject jo){
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+ jsonToXml(jo, "");
return xml;
}

public static String jsonToXml(String json, Mode mode, String newRootName) {
return jsonToXml(json, Xml.XmlStringBuilder.Step.TWO_SPACES, mode, newRootName);
}
/**
* json object to xml
*
* @param jo JSONObject
* @param gt "\n" shifter
*
* @return XML
*
*/
@SuppressWarnings("rawtypes")
private static String jsonToXml(JSONObject jo, String gt) {
StringBuffer xmlStr = new StringBuffer();
try {
JSONObject payload = jo.getJSONObject("payload");
JSONArray children = jo.getJSONArray("children");

// core code
public static Map<String, Object> forceAttributeUsageOverride(Map<String, Object> map) {
Map<String, Object> outMap = newLinkedHashMap();
for (Map.Entry<String, Object> entry : map.entrySet()) {
// poco dedicated conversion
if (entry.getKey().equals("payload")) {
makeAttributePoco(outMap, entry);
} else if (entry.getKey().equals("children")) {
for (Object mapObject : (List) entry.getValue()) {
String name = (String) ((Map<String, Object>) mapObject).get("name");
outMap.put(name, forceAttributeUsageOverride((Map<String, Object>) mapObject));
}
} else {
outMap.put(
entry.getValue() instanceof Map
|| entry.getValue() instanceof List
|| entry.getKey().startsWith("-")
? entry.getKey()
: "-" + entry.getKey(),
makeAttributeUsage(entry.getValue()));
}
}
return outMap;
}
xmlStr.append(gt);
xmlStr.append("<");
String name = String.join("__",payload.get("name").toString().split(" "));

public static String valueJoinString(List<Object> objectList) {
if (objectList == null || objectList.isEmpty()) return "[]";
StringBuilder result = new StringBuilder("[");
for (int i = 0; i < objectList.size() - 1; i++) {
result.append(objectList.get(i).toString());
result.append(",");
}
result.append(objectList.get(objectList.size() - 1)).append("]");
return result.toString();
}
if (name.equals("<Root>"))name = "Root";
name = escapingSpecialCharacters(name);

@SuppressWarnings("unchecked")
private static void makeAttributePoco(Map<String, Object> outMap, Map.Entry<String, Object> entry) {
HashMap<String, Object> tempMap = (HashMap<String, Object>) entry.getValue();
for (String attributeName : tempMap.keySet()) {
if (tempMap.get(attributeName) instanceof LinkedHashMap) {
if (attributeName.equals("zOrders")) {
Map map = (Map) tempMap.get("zOrders");
outMap.put("-global", String.valueOf(map.get("global")));
outMap.put("-local", String.valueOf(map.get("local")));
continue;
xmlStr.append(name);
xmlStr.append(getAttrStr(payload));
xmlStr.append(">\n");
if (children!=null){
for(int i = 0; i < children.size(); i++) {
JSONObject child = children.getJSONObject(i);
xmlStr.append(jsonToXml(child, gt + "\t"));
}
Object object = forceAttributeUsageOverride((Map) tempMap.get(attributeName));
outMap.put(attributeName, object);
} else if (tempMap.get(attributeName) instanceof List) {
// put prefixed "-" with means the value is an attribute
outMap.put("-" + attributeName, valueJoinString((List<Object>) tempMap.get(attributeName)));
} else {
outMap.put("-" + attributeName, String.valueOf(tempMap.get(attributeName)));
}
xmlStr.append(gt);
xmlStr.append("</");
xmlStr.append(name);
xmlStr.append(">\n");
} catch (Exception e) {
return "<error>1</error>";
}
return xmlStr.toString();
}

@SuppressWarnings("unchecked")
private static Object makeAttributeUsage(Object value) {
final Object result;
if (value instanceof List) {
List<Object> values = newArrayList();
for (Object item : (List) value) {
values.add(item instanceof Map ? forceAttributeUsageOverride((Map) item) : item);
public static StringBuilder getAttrStr(JSONObject payload){
StringBuilder sb = new StringBuilder();
sb.append(" ");
for (Map.Entry<String, Object> stringObjectEntry : payload.entrySet()) {
Map.Entry entry = (Map.Entry) stringObjectEntry;
String key = entry.getKey().toString();
String val = entry.getValue().toString();
if (key.equals("zOrders")){
JSONObject zOrders = JSONObject.parseObject(val);
sb.append(String.format("global=\"%s\" ", zOrders.get("global")));
sb.append(String.format("local=\"%s\" ", zOrders.get("local")));
}else if (key.equals("components")){
val = val.replace("\"","");
sb.append(String.format("%s=\"%s\" ", key, val));
} else {
val = escapingSpecialCharacters(val);
sb.append(String.format("%s=\"%s\" ", key, val));
}
result = values;
} else if (value instanceof Map) {
result = forceAttributeUsageOverride((Map) value);
} else {
result = value;
}
return result;
return sb;
}

@SuppressWarnings("unchecked")
public static String jsonToXml(
String json, Xml.XmlStringBuilder.Step identStep, Mode mode, String newRootName) {
Object object = Json.fromJson(json);
final String result;
if (object instanceof Map) {
if (mode == Mode.FORCE_ATTRIBUTE_USAGE) {
result = Xml.toXml(forceAttributeUsageOverride((Map) object), identStep, newRootName);
} else if (mode == Mode.DEFINE_ROOT_NAME) {
result = Xml.toXml((Map) object, identStep, newRootName);
} else if (mode == Mode.REPLACE_NULL_WITH_EMPTY_VALUE) {
result = Xml.toXml(replaceNullWithEmptyValue((Map) object), identStep, newRootName);
} else if (mode == Mode.REPLACE_EMPTY_STRING_WITH_EMPTY_VALUE) {
result =
Xml.toXml(
replaceEmptyStringWithEmptyValue((Map) object),
identStep,
newRootName);
} else if (mode == Mode.FORCE_ADD_ROOT_JSON_TO_XML
&& !Xml.XmlValue.getMapKey(object).equals(ROOT)) {
final Map<String, Object> map = U.newLinkedHashMap();
map.put(newRootName, object);
result = Xml.toXml(map, identStep);
} else if (mode == Mode.FORCE_REMOVE_ARRAY_ATTRIBUTE_JSON_TO_XML) {
result = Xml.toXml((Map) object, identStep, newRootName, Xml.ArrayTrue.SKIP);
} else if (mode == Mode.FORCE_REMOVE_ARRAY_BOOLEAN_NUMBER_ATTRIBUTES_JSON_TO_XML) {
result =
Xml.toXml(
replaceNumberAndBooleanWithString((Map) object),
identStep,
newRootName,
Xml.ArrayTrue.SKIP);
} else {
result = Xml.toXml((Map) object, identStep);
}
return result;
}
return Xml.toXml((List) object, identStep);
private static String escapingSpecialCharacters(String originStr){
if (originStr==null)return null;
originStr = originStr.replace("&","&amp;");
originStr = originStr.replace("<","&lt;");
originStr = originStr.replace(">","&gt;");
originStr = originStr.replace("\"","&quot;");
originStr = originStr.replace("'","&apos;");
return originStr;
}
}
7 changes: 3 additions & 4 deletions src/test/java/org/cloud/sonic/driver/poco/PocoDriverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ public static void beforeClass() {

@Test
public void testPageSource() throws SonicRespException {
Assert.assertEquals("Root", pocoDriver.getPageSource().getPayload().getType());
// Assert.assertEquals("Root", pocoDriver.getPageSource().getPayload().getType());
Assert.assertTrue(pocoDriver.getPageSourceForJsonString().length() > 0);
Assert.assertNotNull(pocoDriver.getPageSourceForXmlElement().toString());
System.out.println(pocoDriver.getPageSourceForXmlElement().toString());
}

@Test
public void testFindElement() throws SonicRespException {
String expression = "poco(\"btn_start\").child(text=\"Start\")[1]";
// String expression = "Root > children > MEHolo > children > AnchorManager";
// String expression = "//*[@text=\"Start\" and @type=\"Text\"]";
String expression = "poco(\"playDragAndDrop\").child(\"star\")[4]";
// String expression = "star";
List<PocoElement> pocoElements = pocoDriver.findElements(PocoSelector.POCO, expression);
System.out.println(pocoElements.size());
for (PocoElement pocoElement : pocoElements) {
Expand Down
Loading

0 comments on commit 4fa4e8d

Please sign in to comment.