Я пытаюсь найти ассоциации между классами в проекте.
context: Я использую инфраструктуру System.Xml в c # для доступа к XML-файлу и получения необходимой информации.После этого я создаю файл JSON, который должен выглядеть следующим образом:
{
"data": [
{
"name": "<Class>",
"attributes": [
{
"name": "<name>",
"type": "<type>"
}
],
"methods": [
{
"name": "<name>",
"returnType": "<returnType>"
}
],
"subclasses": [
"<Class>",
"<Class>"
],
"components": [
"<Class>",
"<Class>"
],
"associations": [
"<Class>",
"<Class>"
]
}
]
}
Мне удалось создать массив данных, имя класса, его атрибуты, их типы и, наконец, методы.Следующим шагом является получение остатка, в котором я застрял.
Это то, что я сделал до сих пор:
PS: (это не показывает мою попытку решить проблему, потому что я действительно не уверен, с чего начать.)
using Newtonsoft.Json;
using System;
using System.IO;
using System.Xml;
[Serializable]
class Program
{
protected static void Main(string[] args)
{
XmlDocument xmlBefore, xmlAfter;
//XmlNodeList attr, meth;
XmlNode name, attributes, methods; // superClasses, subClasses,
components, associations; //<-- these are our constraints
//Create an xml doc for existing file
xmlBefore = new XmlDocument();
//load project
xmlBefore.Load("../../../../assets/tests/sample/singleClass.xml");
XmlNode root = xmlBefore.DocumentElement;
//this is needed to make xpath queries
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmlBefore.NameTable);
namespaceManager.AddNamespace("src", "http://www.srcML.org/srcML/src");
name = GetClassName(xmlBefore, namespaceManager);
attributes = GetAttributes(xmlBefore, namespaceManager);
methods = GetMethods(xmlBefore, namespaceManager);
xmlAfter = new XmlDocument();
XmlNode data, className, classAttributes, classMethods;
className = ImportNode(name, xmlBefore, xmlAfter);
classAttributes = ImportNode(attributes, xmlBefore, xmlAfter);
classMethods = ImportNode(methods, xmlBefore, xmlAfter);
data = xmlAfter.CreateElement("data");
data.AppendChild(className);
data.AppendChild(classAttributes);
data.AppendChild(classMethods);
xmlAfter.AppendChild(data); Console.WriteLine(xmlAfter.InnerXml);
/***** Will use later *****/
try
{
String path = "../../../../assets/xml2json.json";
// serialize JSON to a string and then write string to a file
File.WriteAllText(path, JsonConvert.SerializeObject(xmlAfter));
// serialize JSON directly to a file
using (StreamWriter file = File.CreateText(path))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, xmlAfter);
}
}
catch (Exception u)
{
Console.WriteLine(u.ToString());
}
}
//----------------------------------------------------------------------------------------------------------------
//
//Methods
//
//----------------------------------------------------------------------------------------------------------------
public static String XmlToJson(XmlDocument xmlFile)
{
return JsonConvert.SerializeXmlNode(xmlFile);
}
/*Imports nodes in a list from one document to another */
public static XmlNode ImportNodes(XmlNodeList list, XmlDocument originDoc, XmlDocument destinationDoc)
{
//you cant really just reference a node from one doc to another so you need to import them first
//create a export node that stores import
XmlNode exportNode = destinationDoc.CreateElement("exportNode");
foreach (XmlNode node in list)
{
exportNode.AppendChild(destinationDoc.ImportNode(node, true));
}
return exportNode;
}
public static XmlNode ImportNode(XmlNode node, XmlDocument originDoc, XmlDocument destinationDoc)
{
//you cant really just reference a node from one doc to another so you need to import them first
return destinationDoc.ImportNode(node, true);
}
//----------------------------------------------------------------------------------------------------------------
//
//WARNING: hard coded teritorry yeeehhaaww
//the methods below are only reusable for OUR GROUP PROJECT (DIT3**)
//
//----------------------------------------------------------------------------------------------------------------
public static XmlNode GetClassName(XmlDocument xDoc, XmlNamespaceManager nsm)
{
XmlNode classNameNode = xDoc.CreateElement("name");
classNameNode = xDoc.DocumentElement.SelectSingleNode("/src:unit/src:class/src:name", nsm);
return classNameNode;
}
public static XmlNode GetAttributes(XmlDocument xDoc, XmlNamespaceManager nsm)
{
XmlNodeList attributeList = xDoc.DocumentElement.SelectNodes("/src:unit/src:class//src:decl_stmt//src:decl", nsm);
XmlNode attributeNode = xDoc.CreateElement("attributes");
//we only need type, name;
foreach (XmlNode node in attributeList)
{
String type, name;
//retrive the nodes we need and store their value
type = node.SelectSingleNode("./src:type", nsm).InnerText;
//if there is a final in a type string, remove it
if (type.Length > 5 && type.Substring(0, 5).Equals("final"))
{
type = type.Substring(5, (type.Length - 5));
}
name = node.SelectSingleNode("./src:name", nsm).InnerText;
//create a new element
XmlElement attribute, typeElement, nameElement;
typeElement = xDoc.CreateElement("type");
typeElement.InnerText = type;
nameElement = xDoc.CreateElement("name");
nameElement.InnerText = name;
attribute = xDoc.CreateElement("attribute");
attribute.AppendChild(nameElement);
attribute.AppendChild(typeElement);
//append the child to the original node
attributeNode.AppendChild(attribute);
}
return attributeNode;
}
public static XmlNode GetMethods(XmlDocument xDoc, XmlNamespaceManager nsm)
{
XmlNodeList methodList = xDoc.DocumentElement.SelectNodes("/src:unit/src:class//src:function", nsm);
XmlNode methodNode = xDoc.CreateElement("methods");
//we only need type, name
foreach (XmlNode node in methodList)
{
String type, name;
//retrive the nodes we need and store their value
type = node.SelectSingleNode("./src:type/src:name", nsm).InnerText;
name = node.SelectSingleNode("./src:name", nsm).InnerText;
//create elements
XmlElement method, methodName, methodType;
methodName = xDoc.CreateElement("name");
methodName.InnerText = name;
methodType = xDoc.CreateElement("type");
methodType.InnerText = type;
method = xDoc.CreateElement("method");
method.AppendChild(methodName);
method.AppendChild(methodType);
//append results
methodNode.AppendChild(method);
}
return methodNode;
}
public static XmlNode GetSubClasses(XmlNodeList list, XmlDocument originDoc, XmlDocument destinationDoc)
{
return null;
}
public static XmlNode GetSuperClasses(XmlNodeList list, XmlDocument originDoc, XmlDocument destinationDoc)
{
return null;
}
public static XmlNode GetComponents(XmlNodeList list, XmlDocument
originDoc,
XmlDocument destinationDoc)
{
return null;
}
}
XML-файл, который я бы использовал (однако идея заключается в том, чтобы заставить его работать с любым XML):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<unit xmlns="http://www.srcML.org/srcML/src" revision="0.9.5" language="Java" filename="Employee.java"><package> package <name>assignment3</name>;</package>
<class><specifier>public</specifier> class <name>Employee</name> <super><implements>implements <name><name>Comparable</name><argument_list type="generic"><<argument><name>Employee</name></argument>></argument_list></name></implements></super><block>{
<decl_stmt><decl><specifier>private</specifier> <type><specifier>final</specifier> <name>int</name></type> <name>EQUAL_RESULT</name> <init>= <expr><literal type="number">0</literal></expr></init></decl>;</decl_stmt>
<decl_stmt><decl><specifier>private</specifier> <type><specifier>final</specifier> <name>int</name></type> <name>INVERSE</name> <init>= <expr><operator>-</operator><literal type="number">1</literal></expr></init></decl>;</decl_stmt>
<decl_stmt><decl><specifier>private</specifier> <type><name>String</name></type> <name>name</name></decl>;</decl_stmt>
<decl_stmt><decl><specifier>private</specifier> <type><name>String</name></type> <name>id</name></decl>;</decl_stmt>
<decl_stmt><decl><specifier>private</specifier> <type><name>double</name></type> <name>grossSalary</name></decl>;</decl_stmt>
<decl_stmt><decl><specifier>private</specifier> <type><specifier>final</specifier> <name>double</name></type> <name>TAX</name> <init>= <expr><literal type="number">0.1</literal></expr></init></decl>;</decl_stmt>
<decl_stmt><decl><specifier>public</specifier> <specifier>static</specifier> <type><name>String</name></type> <name>choose</name></decl>;</decl_stmt>
<decl_stmt><decl><specifier>public</specifier> <specifier>static</specifier> <type><name>String</name></type> <name>orderBy</name></decl>;</decl_stmt>
<constructor><specifier>public</specifier> <name>Employee</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>name</name></decl></parameter>, <parameter><decl><type><name>String</name></type> <name>id</name></decl></parameter>, <parameter><decl><type><name>double</name></type> <name>grossSalary</name></decl></parameter>)</parameter_list> <block>{
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>name</name></name><operator>=</operator><name>name</name></expr>;</expr_stmt>
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>id</name></name><operator>=</operator><name>id</name></expr>;</expr_stmt>
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>grossSalary</name></name><operator>=</operator> <name>grossSalary</name></expr>;</expr_stmt>
}</block></constructor>
<comment type="block">/*
* this method is to keep the getGrossSalary() from changing,
* so all the changes will affect calculateSalary() not getGrossSalary().
*/</comment>
<function><specifier>public</specifier> <type><name>double</name></type> <name>calculateSalary</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name><name>this</name><operator>.</operator><name>grossSalary</name></name></expr>;</return>
}</block></function>
<function><specifier>public</specifier> <type><name>double</name></type> <name>getNetSalary</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name><name>this</name><operator>.</operator><name>grossSalary</name></name><operator>-</operator> <operator>(</operator><name><name>this</name><operator>.</operator><name>grossSalary</name></name><operator>*</operator><name>TAX</name><operator>)</operator></expr>;</return>
}</block></function>
<function><annotation>@<name>Override</name></annotation>
<specifier>public</specifier> <type><name>int</name></type> <name>compareTo</name><parameter_list>(<parameter><decl><type><name>Employee</name></type> <name>newEmployee</name></decl></parameter>)</parameter_list> <block>{
<decl_stmt><decl><type><name>int</name></type> <name>result</name> <init>= <expr><call><name><name>this</name><operator>.</operator><name>getName</name></name><argument_list>()</argument_list></call><operator>.</operator><call><name>compareToIgnoreCase</name><argument_list>(<argument><expr><call><name><name>newEmployee</name><operator>.</operator><name>getName</name></name><argument_list>()</argument_list></call></expr></argument>)</argument_list></call></expr></init></decl>;</decl_stmt>
<if>if <condition>(<expr><name>result</name> <operator>==</operator> <name>EQUAL_RESULT</name></expr>)</condition><then> <block>{
<expr_stmt><expr><name>result</name> <operator>=</operator> <call><name><name>Double</name><operator>.</operator><name>compare</name></name><argument_list>(<argument><expr><call><name><name>this</name><operator>.</operator><name>getGrossSalary</name></name><argument_list>()</argument_list></call></expr></argument>, <argument><expr><call><name><name>newEmployee</name><operator>.</operator><name>getGrossSalary</name></name><argument_list>()</argument_list></call></expr></argument>)</argument_list></call></expr>;</expr_stmt>
}</block></then></if>
<return>return <expr><name>result</name></expr>;</return>
}</block></function>
<function><specifier>public</specifier> <type><name>String</name> </type> <name>getName</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name>name</name></expr>;</return>
}</block></function>
<function><specifier>public</specifier> <type><name>void</name></type> <name>setName</name><parameter_list>(<parameter><decl><type><name>String</name></type> <name>name</name></decl></parameter>)</parameter_list> <block>{
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>name</name></name> <operator>=</operator> <name>name</name></expr>;</expr_stmt>
}</block></function>
<function><specifier>public</specifier> <type><name>String</name></type> <name>getId</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name>id</name></expr>;</return>
}</block></function>
<function><specifier>public</specifier> <type><name>double</name></type> <name>getGrossSalary</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name>grossSalary</name></expr>;</return>
}</block></function>
<function><specifier>public</specifier> <type><name>void</name></type> <name>setGrossSalary</name><parameter_list>(<parameter><decl><type><name>double</name></type> <name>grossSalary</name></decl></parameter>)</parameter_list> <block>{
<expr_stmt><expr><name><name>this</name><operator>.</operator><name>grossSalary</name></name><operator>=</operator><name>grossSalary</name></expr>;</expr_stmt>
}</block></function>
<function><specifier>public</specifier> <type><name>String</name></type> <name>toString</name><parameter_list>()</parameter_list> <block>{
<return>return <expr><name><name>this</name><operator>.</operator><name>name</name></name><operator>+</operator><literal type="string">"'s gross Salary is of "</literal><operator>+</operator> <name><name>this</name><operator>.</operator><name>grossSalary</name></name><operator>+</operator><literal type="string">" SEK per month. "</literal></expr>;</return>
}</block></function>
<comment type="line">// CHALLENGE 1</comment>
<comment type="block">/*@Override
*/</comment>
}</block></class>
</unit>