الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

التعامل مع ملفات xml

بدأه abo_mona في 4 سبتمبر 2010 · 29 رد · 1,849 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

خواتم مباركة وكل عام وانتم بالف خير

اريد معرفة كيف اقوم بقرائه من ملفين اكس ام ال وعمل مقارنة بينهم والحصول على نتيجة هذة المقارنة

فمثلا ادي ملفين كل ملف فية بيانات مختلفة واريد ان اقوم بمقارنة كل صف مع الصف المقابل لة بالملف الاخر والرجوع بنتيجة هذة المقارنة

انا اريد ان اقراء من ملفين واقوم بالمقانة بينهم

هذا xml

الملف الاول

<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- definition of simple elements -->

<xs:element name="identifier" type="xs:positiveInteger"/>

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

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

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

<xs:element name="RHS" type="xs:mixed"/>

<xs:element name="importance">

</xs:element>

<!-- definition of complex elements -->

<xs:element name="u-rule">

<xs:complexType>

<xs:sequence>

<xs:element ref="identifier"/>

<xs:element ref="description"/>

<xs:element name="condition">

<xs:complexType>

<xs:sequence>

<xs:element ref="LHS"/>
 <xs:element ref="OP"/>

<xs:element ref="RHS"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element ref="importance"/>

</xs:element>

</xs:schema>

الملف الثاني

<?xml version="1.0" encoding="UTF-8" ?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<!-- definition of simple elements -->

<xs:element name="identifier" type="xs:positiveInteger"/>

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

<!-- definition of attributes -->

<xs:attribute name="valueDataType" type="xs:string"/>

<!-- definition of complex elements -->

<xs:element name="p-rule">

<xs:complexType>

<xs:sequence>

<xs:element ref="identifier"/>

<xs:element ref="value"/>

<xs:attribute ref="valueDataType" use="required"/>

</xs:element>

</xs:schema>

الذي اريدة ان اقارن بين بين البيانات التي في الملف الاول والتي هي في الRHS مع البيانات التي في value في الملف الثاني

حيث ان ال identifier مشترك في الاثنين وثابت .

وسيكون هناك قيمة احصل عليها من تماثل اي قيمتين .

اتمنى ان اكون وصلت لكم الفكرة .

مع خالص شكري لكم

تم تعديل هذه المشاركة بواسطة abo_mona في 4 سبتمبر 2010 في 23:02

#2

الملفات عندك ليست well formed، فبعض الوسوم غير مغلقة. يجب أن تصححها أولا

لم أفهم بالضبط ماذا تريد. عموما، هذا الكود يقوم بفتح الملفين، ويسترجع ال attribute type الخاصة ب RHS و value ويطبعها. عدله لكي يتلاءم مع حاجتك

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class NewClass {

	public static void main(String[] args) throws SAXException, ParserConfigurationException, IOException {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuidler = factory.newDocumentBuilder();
		Document document1 = documentBuidler.parse(new File("path_to_xml1"));
		Document document2 = documentBuidler.parse(new File("path_to_xml2"));

		Node rhs = null;
		NodeList list1 = document1.getElementsByTagName("xs:element");
		for (int i = 0; i < list1.getLength(); i++) {
			Node n = list1.item(i);
			if (n.hasAttributes() && n.getAttributes().getNamedItem("name") != null
					&& n.getAttributes().getNamedItem("name").getNodeValue().equals("RHS")) {
				rhs = n;
				break;
			}
		}
		Node value = null;
		NodeList list2 = document2.getElementsByTagName("xs:element");
		for (int i = 0; i < list2.getLength(); i++) {
			Node n = list2.item(i);
			if (n.hasAttributes() && n.getAttributes().getNamedItem("name") != null
					&& n.getAttributes().getNamedItem("name").getNodeValue().equals("value")) {
				value = n;
				break;
			}
		}
		System.out.println("RHS= " + rhs.getAttributes().getNamedItem("type").getNodeValue());
		System.out.println("value= " + value.getAttributes().getNamedItem("type").getNodeValue());
	}
}
#3

اشكرك اخي على الرد السريع ولو ممكن تشرح الكود

وكنت اريد اقوم بعمل ثلاث خطوات

الخطوة الاولى ان اقارن ال قيمة identifier بالملف الاول مطابقة للقيمة في الملف الثاني

الخطوة الثانية اذا كانت مطابقة فانتقل الى المقارنة بين RHS في الملف الاول مع ال value في الملف الثاني والمشكله عندي ان القيم قد تكون حروف وقد تكون ارقام وايضا لدي الop وهو العلاقة بين القيمة التي في RHS وال value

لان العلاقة قد تكون (RHS=value ) او (RHS<= value) فكيف يمكنني عمل هذا من خلال الجافا

الخطوة الثالثة والاخيرة وهي ان عندي قيمة في importance حيث ان في حالة ان القيمة متساوية او اقل منها فانني انتقل الى ال العنصر importance حيث اخذ القيمة التي فية واكمل بها البرنامج

اعذرني للاطاله واشكرك اخي مقدما

#4
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder documentBuidler = factory.newDocumentBuilder();

الهدف من هذين السطرين هو الحصول على كائن من فئة DocumentBuilder، هذا الكائن هو الذي يمكننا من الحصول على كائن Document. الفئة Document تمثل ال DOM tree الخاصة بالملف الذي نريد التعامل معه

Document document1 = documentBuidler.parse(new File("path_to_xml1")); 
Document document2 = documentBuidler.parse(new File("path_to_xml2"));

نحصل هنا على كائنين Document، كل كائن يمثل ملفا xml.

NodeList list1 = document1.getElementsByTagName("xs:element");

نسترجع لائحة بجميع ال nodes التي تحمل إسم xs:element، ونخزنها في كائن NodeList

for (int i = 0; i < list1.getLength(); i++) { 	Node n = list1.item(i);

نمر على كل ال nodes الموجودة في اللائحة

	if (n.hasAttributes() && n.getAttributes().getNamedItem("name") != null  && n.getAttributes().getNamedItem("name").getNodeValue().equals("RHS")) {

نتحقق من أن ال node الحالي يحتوي على attributes، وأن من بين هذه ال attributes بوجد attribute باسم "name" وأنه يساوي RHS،

		rhs = n; 
		break; 	} }

إذا تحققت هذه الشروط نجعل المتغير rhs يساوي ال node الحالي ثم نخرج من ال loop نفس المبدأ بالنسبة بقية الكود

اقتباس
الخطوة الاولى ان اقارن ال قيمة identifier بالملف الاول مطابقة للقيمة في الملف الثاني

ما الذي تريد مقارنته؟ فلا أحد من هذه الوسوم لديه قيمة، فقط ال attribute type هو الموجود، وقد بينت كيف تحصل على قيمته في السطرين الأخيرين من الكود. يكفي أن تغير RHS و value ب identifier وتطبق نفس الكود

تم تعديل هذه المشاركة بواسطة herch في 6 سبتمبر 2010 في 01:54

#5

الملفات المذكورة في السؤال هي XML Schema وليست لـ XML

لم أقرأ كود الأخ herch واعتذر مقدماً إن كانت الإجابة متشابهه ...

قم بقراءة أسماء جميع الـ Element للملفين . يفضل فصل الـ Elements على أساس الـ Type فهناك simpleType و complexTYpe و هذا الأخير يحتاج للمزيد من العمل حيث سنقوم بمقارنة الـ attribute و الـ elements الداخلية ... هناك أشياء أخرى يجب مقارنتها مثل الـ restriction , indicators ....

وجود element في أحدهما وعدم وجوده في الآخر يقضي بان هذا جزء من الإختلاف ...

ليس بالضرورة كون أسماء الـ elements , attribute .. هي نفسها حتى نقضي بتشابه الملفين .. أعني لا تقارن على الإسم وإلا فلا فائدة ترجى من المقارنة.

أظن هناك بعض الأدوات توفر عمل ذلك

DiffDog

سبب التعديل :

فصل بدلاً عن فضل (خطأ أثناء الكتابة)

تم تعديل هذه المشاركة بواسطة YaSeenTA في 6 سبتمبر 2010 في 07:20

#6

لتوضيح ما قصدت في ردي السابق .

ما تريد عمله هو XML Schema Structure Comparing وليس XML Schema Content Comparing.

ستحتاج لقراءة وفهم جيد لـ XSD ..

#7

الملف الاول

<?xml version="1.0" encoding="UTF-8"?>
<u-rule>
<root>
    <identifier> 1 </identifier>
    <description> send tow 3rd party </description> 
    <condition>
      <LHS> send tow 3rd party </LHS>
      <OP> = </OP>
      <RHS>yes </RHS>
    </condition>
   <importance> low </importance>
</root>
<root>
<identifier> 2 </identifier>
    <description> price sms </description> 
    <condition>
      <LHS> price sms </LHS>
      <OP> = </OP>
      <RHS>0.25 </RHS>
    </condition>
 <importance> medium </importance>
</root>
<root>
<identifier> 3 </identifier>
    <description> price MMS </description> 
    <condition>
      <LHS> price MMS </LHS>
      <OP> = </OP>
      <RHS>0.75 </RHS>
    </condition>
    <importance> high </importance>
</root>

</u-rule>

الملف الثاني

<u-rule>
<root>
    <identifier> 1 </identifier>
      <value>yes </value>
</root>
<root>
<identifier> 2 </identifier>
      <value>0.25 </value>
</root>
<root>
<identifier> 4 </identifier>
      <value>0.75 </value>   
</root>

</u-rule>

الفكرة هي ان الملف الاول يقوم المستخدم باختيار تفضيلاتة وادخال القيم المناسبة له للخدمات التي يريدها او لخصوصيتة وايضا يقوم بتحديد اهمية هذة الخدمة(importance)وقد عملنا ثلاثة مستويات ولكل مستوى قيمة حقيقية تناضرة يقوم المستخدم بادخالها في اول البرنامج , وحيث هذا الملف ثابت وفيه كل الخدمات والمستخدم يختار الخدمة المفضلة له والسعر الذي يريدة

فقد يختار المستخدم الخدمات رقم 1,2,4,5, ولايختار بقية الخدمات .

الملف الثاني هو ماتقدمة الشركة من خدمات واسعارها وستكون هناك العديد من الشركات وكل شركة ترسل الملف وفية رقم الخمة وسعرها .

فانا اريد ان اقوم بعمل برنامج يقوم بعملية المقارنة بين بيانات المستخدم والبيانات التي لدى كل شركة والرجوع للمستخدم بافضل شركة التي تحقق اكبر قدر من تفضيلاتة .

وهناك

الملفين مشتركين في ال identifier حيث انه يشير الى رقم الخدمة (rule) فبعد ان اتاكد من ان القيمه متساوية

انتقل للمرحلة الثانية وهي ان اقوم باخذ القيمة التي في ال RHS في الملف الاول ومقارنتها من خلال المعامل الموجود في OP في الملف الاول مع القيمة الموجودة في الملف الثاني value اذا كانت القيمة متساوية وتحققت

المرحلة التالية ان اقوم بالنضر الى القيمة ال importance واقوم بتجميع العدد لكل importance فمثلا عندي عندي ٣ high وهكذا

اشكركم على تفاعلكم وجزاكم الله الف خير

#8

إن كانت الـ XML schema لملفات الـ XML التي تتعامل معها في برنامجك هي تلك التي وضعتها في أول السؤال فجرب هذا الكود ...

import org.w3c.dom.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


import org.xml.sax.SAXException;

public class XPathDemo {
	static Map <String,Integer> importanceInfo= new HashMap<String,Integer>();


  public static void main(String[] args){ 

    try {
    	chkImportance("company1.xml","customer.xml");
	System.out.println(importanceInfo.toString());
	} catch (XPathExpressionException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ParserConfigurationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SAXException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  }

  public static void chkImportance(String companyFile ,String customerFile) throws ParserConfigurationException, SAXException, 
  IOException, XPathExpressionException {

	    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	          domFactory.setNamespaceAware(true); 
	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(customerFile);
	    XPath xpath = XPathFactory.newInstance().newXPath();
	    //initialize importanceInfo
	    XPathExpression expr = xpath.compile("//importance/text()");
	    Object result = expr.evaluate(doc, XPathConstants.NODESET);
	    NodeList nodes = (NodeList) result;
	    for(int i=0;i<nodes.getLength();i++)
	    	importanceInfo.put(nodes.item(i).getNodeValue(),0); 

	    doc = builder.parse(companyFile);
	    expr = xpath.compile("//identifier/text()");

	    result = expr.evaluate(doc, XPathConstants.NODESET);
	    nodes = (NodeList) result;
	    int allRules= nodes.getLength();
	    for (int i = 0; i < allRules; i++) {
	    	String nodeID=nodes.item(i).getNodeValue();
			//System.out.print("node id:"+nodeID); 
			expr = xpath.compile("//root[identifier="+nodeID+"]/value/text()");
			result = expr.evaluate(doc, XPathConstants.NODESET);
			NodeList nodes1 = (NodeList) result;
		    nodes1 = (NodeList) result;
		    String nodeValue="";
		    if(nodes1.getLength()!=0){//We don't use for loop since we have only one element as shown in XSD file
		    	 nodeValue=((NodeList)result).item(0).getNodeValue();
		    	 //System.out.print(" value: "+nodeValue);
		    } 	 
			DocumentBuilder builder1 = domFactory.newDocumentBuilder();
			Document doc1 = builder1.parse(customerFile);
			XPath xpath1 = XPathFactory.newInstance().newXPath();
			XPathExpression expr1 = xpath1.compile("//root[.//identifier="+nodeID+"]/condition/RHS/text()");
			Object result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			String RHS="";
			if(nodes1.getLength()!=0){
				RHS=nodes1.item(0).getNodeValue();
				//System.out.print(" RHS: "+RHS);
			}
			else
				continue;
			expr1 = xpath1.compile("//root[.//identifier="+nodeID+"]/condition/OP/text()");
			result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			String OP="";
			if(nodes1.getLength()!=0){
				OP=nodes1.item(0).getNodeValue();
				//System.out.println(" OP: "+OP);	
			}
			expr1 = xpath1.compile("//root[identifier="+nodeID+"]/condition[RHS"+OP+"'"+nodeValue+"'"+"]/RHS/text()");
			result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			if(nodes1.getLength()!=0){
				//check importance				
				expr1 = xpath1.compile("//root[identifier="+nodeID+" and condition[RHS"+OP+"'"+nodeValue+"'"+"]]/importance/text()");
				result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
				nodes1 = (NodeList) result1;
				String impStr=nodes1.item(0).getNodeValue();
				int impValue=importanceInfo.get(impStr);				
				importanceInfo.put(impStr, ++impValue);
				//System.out.println(nodes1.item(0).getNodeValue());
			}		
	    }
  }
}

حيث companyFile هو ملف الـ XML الثاني , customerFile هو ملف الـ XML الأول (المقصود هنا الملفين في آخر رد لك , ملفات الـ XML وليست ملفات XSD )

ربما هناك طريقة أفضل من هذه , انتظر ردود بقية الأخوة.

ملحوظة: في ملف الـ XSD الأول قيم الـ importance هل هي غير محدودة و المستخدم يقوم بتحديدها ...

من فهمي المتواضع لما شرحته أعتقد أنها محدودة بقيم يختارها المستخدم كـ low, medium, high ..إلخ . إن كانت كذلك لماذا لا تستخدم enum لتحديدها...

تم تعديل هذه المشاركة بواسطة YaSeenTA في 6 سبتمبر 2010 في 22:22

1
#9

هذا مثال يمكن أن تنطلق منه. لم أقم بالجزء الخاص بال importance.

لفهم الجزء الخاص بال XPathن يمكن مراجعة هذا الموضوع /index.php?showtopic=212235 أو هذا الموقع http://www.w3schools.com/xpath/default.asp

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class NewClass {

	public static void main(String[] args) throws SAXException, ParserConfigurationException, IOException, XPathExpressionException {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuidler = factory.newDocumentBuilder();
		Document document1 = documentBuidler.parse(new File("/home/issam/xml1.xml"));
		Document document2 = documentBuidler.parse(new File("/home/issam/xml2.xml"));

		XPathFactory xpathFactory = XPathFactory.newInstance();
		XPath xpath = xpathFactory.newXPath();

		NodeList rootNodes1 = document1.getElementsByTagName("root");
		NodeList rootNodes2 = document2.getElementsByTagName("root");

		for (int i = 0; i < rootNodes1.getLength(); i++) {
			Element root = (Element)rootNodes1.item(i);
			Node identifier = root.getElementsByTagName("identifier").item(0);
			String expression = "/u-rule/root[identifier="+identifier.getTextContent()+"]/identifier/text()";
			String identifier2 = xpath.evaluate(expression, document2);
			if (!identifier2.isEmpty()) {
				System.out.println("Identifier found: " + identifier2);
				String rhs = root.getElementsByTagName("RHS").item(0).getTextContent();
				String op = root.getElementsByTagName("OP").item(0).getTextContent();
				String value = xpath.evaluate("/u-rule/root[identifier="+identifier.getTextContent()+" and value" + op + rhs +"]/value/text()", document2);
				if (!value.isEmpty()) {
					System.out.println("Condition satisifed: "+ value + op + rhs);
				}
			}
		}
	}
}
#10

كما قلت في موضوع لي هنا اني جديد على جافا لهذا هنا الكثير ما لا أعلمه ولم أستخدمه من قبل

حل الآخ herch مختصر وأفضل بكثير

فقط هناك خطأ بسيط في الكود وهو هنا معدلاً

String value = xpath.evaluate("/u-rule/root[identifier="+identifier.getTextContent()+" and value" + op + "'"+rhs +"'"+"]/value/text()", document2);

الفكرة بشكل عام واحدة وهي إستخدام xpath ...

#11

المثال الذي وضعتُه لم يكن بديلا للكود الذي كتبتَه.

لم أر ردك إلا بعدما كتبت ردي smile.gif

#12

أعلم ذلك ففارق الوقت ليس كبيراً . وقد لاحظت وجودك أثناء كتابتي للرد. :)

هل بامكانك تشرفني في أول سؤال لي في قسم الجافا ؟

/index.php?showtopic=228125

#13

رأيته لكني لم أعرف الجواب smile.gif كل تعاملي مع ال XPath كان بال DOM blush.gif

#14

لم اقوم بتجربة الكود لانني الان فتحت الجهاز وقراءت الردود فحبيت اشكركم اولاً على تجاوبكم معي ومساعدتي في عمل البرنامج

اكرر شكري وامتناني لكم واتمنى من الله ان يجزيكم خير الجزاء

تم تعديل هذه المشاركة بواسطة abo_mona في 7 سبتمبر 2010 في 02:24

#15
YaSeenTA كتب:

إن كانت الـ XML schema لملفات الـ XML التي تتعامل معها في برنامجك هي تلك التي وضعتها في أول السؤال فجرب هذا الكود ...

import org.w3c.dom.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


import org.xml.sax.SAXException;

public class XPathDemo {
	static Map <String,Integer> importanceInfo= new HashMap<String,Integer>();


  public static void main(String[] args){ 

    try {
    	chkImportance("company1.xml","customer.xml");
	System.out.println(importanceInfo.toString());
	} catch (XPathExpressionException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ParserConfigurationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SAXException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  }

  public static void chkImportance(String companyFile ,String customerFile) throws ParserConfigurationException, SAXException, 
  IOException, XPathExpressionException {

	    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	          domFactory.setNamespaceAware(true); 
	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(customerFile);
	    XPath xpath = XPathFactory.newInstance().newXPath();
	    //initialize importanceInfo
	    XPathExpression expr = xpath.compile("//importance/text()");
	    Object result = expr.evaluate(doc, XPathConstants.NODESET);
	    NodeList nodes = (NodeList) result;
	    for(int i=0;i<nodes.getLength();i++)
	    	importanceInfo.put(nodes.item(i).getNodeValue(),0); 

	    doc = builder.parse(companyFile);
	    expr = xpath.compile("//identifier/text()");

	    result = expr.evaluate(doc, XPathConstants.NODESET);
	    nodes = (NodeList) result;
	    int allRules= nodes.getLength();
	    for (int i = 0; i < allRules; i++) {
	    	String nodeID=nodes.item(i).getNodeValue();
			//System.out.print("node id:"+nodeID); 
			expr = xpath.compile("//root[identifier="+nodeID+"]/value/text()");
			result = expr.evaluate(doc, XPathConstants.NODESET);
			NodeList nodes1 = (NodeList) result;
		    nodes1 = (NodeList) result;
		    String nodeValue="";
		    if(nodes1.getLength()!=0){//We don't use for loop since we have only one element as shown in XSD file
		    	 nodeValue=((NodeList)result).item(0).getNodeValue();
		    	 //System.out.print(" value: "+nodeValue);
		    } 	 
			DocumentBuilder builder1 = domFactory.newDocumentBuilder();
			Document doc1 = builder1.parse(customerFile);
			XPath xpath1 = XPathFactory.newInstance().newXPath();
			XPathExpression expr1 = xpath1.compile("//root[.//identifier="+nodeID+"]/condition/RHS/text()");
			Object result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			String RHS="";
			if(nodes1.getLength()!=0){
				RHS=nodes1.item(0).getNodeValue();
				//System.out.print(" RHS: "+RHS);
			}
			else
				continue;
			expr1 = xpath1.compile("//root[.//identifier="+nodeID+"]/condition/OP/text()");
			result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			String OP="";
			if(nodes1.getLength()!=0){
				OP=nodes1.item(0).getNodeValue();
				//System.out.println(" OP: "+OP);	
			}
			expr1 = xpath1.compile("//root[identifier="+nodeID+"]/condition[RHS"+OP+"'"+nodeValue+"'"+"]/RHS/text()");
			result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
			nodes1 = (NodeList) result1;
			if(nodes1.getLength()!=0){
				//check importance				
				expr1 = xpath1.compile("//root[identifier="+nodeID+" and condition[RHS"+OP+"'"+nodeValue+"'"+"]]/importance/text()");
				result1 = expr1.evaluate(doc1, XPathConstants.NODESET);
				nodes1 = (NodeList) result1;
				String impStr=nodes1.item(0).getNodeValue();
				int impValue=importanceInfo.get(impStr);				
				importanceInfo.put(impStr, ++impValue);
				//System.out.println(nodes1.item(0).getNodeValue());
			}		
	    }
  }
}

حيث companyFile هو ملف الـ XML الثاني , customerFile هو ملف الـ XML الأول (المقصود هنا الملفين في آخر رد لك , ملفات الـ XML وليست ملفات XSD )

ربما هناك طريقة أفضل من هذه , انتظر ردود بقية الأخوة.

ملحوظة: في ملف الـ XSD الأول قيم الـ importance هل هي غير محدودة و المستخدم يقوم بتحديدها ...

من فهمي المتواضع لما شرحته أعتقد أنها محدودة بقيم يختارها المستخدم كـ low, medium, high ..إلخ . إن كانت كذلك لماذا لا تستخدم enum لتحديدها...

كيف يمكنني عمل ذلك؟؟؟ لان المستويات ثلاثة فقط low, medium, high

البرنامج شغال لكن لا يعطيني الاعداد الخاصة بكل مستوى بصورة صحيحة حيث انني اريد فقط ال importance التي حصل للقيمة RHS مطابقة مع ال value في ملف الشركة , حيث ان كل شركة لها ملف خاص واريد تقييم كل شركة ويتم التقييم عن طريق معادلة

sum= W1*X+W2*Y+W3Z

حيث ال3 W1,W2,W

وال X عدد ال importance التي هي high

وال Y عدد ال importance التي هي medium

وال Z عدد ال importance التي هي low

وعندي سؤال كيق يمكنني ان اقوم بمقارنة اكثر من ملف للشركة مع ملف المستخدم ؟؟؟؟ حيث ان ملفات الشركة ليست معروفة فقد تكون ٣ او ٤ او ...

غير معروفه العدد

ولو ممكن تشرح لي الكود من اجل ان استطيع التعديل فية

مع خالص شكري لك

تم تعديل هذه المشاركة بواسطة abo_mona في 7 سبتمبر 2010 في 18:41

#16

قبل أن أضع رد على تساؤلاتك لدي سؤال ...

بالنسبة لملفات الـ XML كيف تقوم بإنشاءها؟ هل تستعمل JAXB ؟

بالنسبة لسؤالك حول نقطة الـ enum التي ذكرتها فكنت أقصد عمل ذلك في ملف الـ XSD ..

هكذا

<xs:simpleType name="importance">
  <xs:restriction base="xs:string">
    <xs:enumeration value="low"/>
    <xs:enumeration value="medium"/>
    <xs:enumeration value="high"/>
  </xs:restriction>
</xs:simpleType>

فحين يتم إنشاء الملف سيكون الخيار هو إحدى الثلاث القيم السابقة ...

اقتباس
البرنامج شغال لكن لا يعطيني الاعداد الخاصة بكل مستوى بصورة صحيحة حيث انني اريد فقط ال importance التي حصل للقيمة RHS مطابقة مع ال value في ملف الشركة , حيث ان كل شركة لها ملف خاص واريد تقييم كل شركة ويتم التقييم عن طريق معادلة

تحتاج لتعديل الكود بالنسبة للجزء الخاص بالإخراج

اقتباس
طريق معادلة

sum= W1*X+W2*Y+W3Z

حيث ال3 W1,W2,W

لم توضح ما هي W1,W2,W3 لذا لم أستخدم المعادلة في الكود الآتي الذي قد يلبي ما تريد :

import org.w3c.dom.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.xml.sax.SAXException;


public class XPathDemo {
	static Map <String,CompanyInfo> importanceInfo=new HashMap<String,CompanyInfo>();
	static Map <String,CustomerInfo> customerInfo= new HashMap<String,CustomerInfo>();


  public static void main(String[] args){ 

    try {
    	//call getCompanyInfo as many time as you need
    	getCompanyInfo("customer.xml","company1.xml");
    	getCompanyInfo("customer.xml","company2.xml");
    	// here you implement your code (equation,comparing...)
        Set<String> imInfo = importanceInfo.keySet();
        Iterator<String> It = imInfo.iterator();                
        while (It.hasNext()) {
            String imLabel = It.next();
            int []imValues=importanceInfo.get(imLabel).getImportanceValue();            
            System.out.println(imLabel + " -> " + imValues[0]+" , "+imValues[1]+" , "+imValues[2]);                
    }

	} catch (XPathExpressionException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ParserConfigurationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SAXException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  }

  private static void getCompanyInfo(String customerFile,String companyFile) throws XPathExpressionException, SAXException, ParserConfigurationException, IOException{
	  //get the information needed from customer's XML file
	  setCustomerInfo(customerFile);
	  // TODO  validate company XML file according to XSD file
	  setCompanyInfo(companyFile);
  }
  private static void setCustomerInfo(String customerFileName)throws SAXException, ParserConfigurationException, IOException, XPathExpressionException {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder documentBuidler = factory.newDocumentBuilder(); 
      Document document1 = documentBuidler.parse(new File(customerFileName)); 
      XPathFactory xpathFactory = XPathFactory.newInstance(); 
      XPath xpath = xpathFactory.newXPath(); 

      NodeList rootNodes1 = document1.getElementsByTagName("root"); 

      for (int i = 0; i < rootNodes1.getLength(); i++) { 
              Element root = (Element)rootNodes1.item(i); 
              Node identifier = root.getElementsByTagName("identifier").item(0); 
              String expression = "/u-rule/root[identifier="+"'"+identifier.getTextContent()+"'"+"]/identifier/text()"; 
              String identifierStr = xpath.evaluate(expression, document1);              
              String rhsStr = root.getElementsByTagName("RHS").item(0).getTextContent(); 
              String opStr = root.getElementsByTagName("OP").item(0).getTextContent();                    
              String importanceValue = root.getElementsByTagName("importance").item(0).getTextContent(); 
              customerInfo.put(identifierStr,new CustomerInfo(rhsStr,opStr,importanceValue));              
      } 	  
  }
  public static void setCompanyInfo(String companyFile)throws SAXException, ParserConfigurationException, IOException, XPathExpressionException {
	  //initializing company information
	  int []importanceValues={0,0,0};	  
	  //you may add some info about the company is the XML file. If you do that change the CompanyInfo class to fit that
	  importanceInfo.put(companyFile, new CompanyInfo(companyFile,importanceValues));
	  // Check javadoc for more information about XPath 
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder documentBuidler = factory.newDocumentBuilder(); 
      Document document2 = documentBuidler.parse(new File(companyFile));
      XPathFactory xpathFactory = XPathFactory.newInstance(); 
      XPath xpath = xpathFactory.newXPath();                        
      NodeList rootNodes2 = document2.getElementsByTagName("root"); 

      for (int i = 0; i < rootNodes2.getLength(); i++) { 
              Element root = (Element)rootNodes2.item(i); 
              String idStr= root.getElementsByTagName("identifier").item(0).getTextContent();
              CustomerInfo cusInfo=customerInfo.get(idStr);
              if(cusInfo!=null){
            	  String value = xpath.evaluate("/u-rule/root[identifier="+"'"+idStr+"'"+" and value" + cusInfo.getOP() + "'"+cusInfo.getRHS() +"'"+"]/value/text()", document2); 
            	  if (!value.isEmpty()) { 
            		  String impStr=cusInfo.getImportance();
                	  int impIx = 0;
                	  //I used indexOf because your file has spaces in the importance value
                	  if(impStr.indexOf("low")!=-1)
                		  impIx=0;
                	  else if(impStr.indexOf("medium")!=-1)
                		  impIx=1;
                	  else if(impStr.indexOf("high")!=-1)
                		  impIx=2;
                	  int []imValues=importanceInfo.get(companyFile).getImportanceValue();
                	  ++imValues[impIx];
            	  } 
              } 	  
      }
  }
}
class CustomerInfo{
	  String rhsValue;
	  String operator;
	  String importance;
	  public CustomerInfo(String rhs,String op,String importanceValue ){
		  this.importance=importanceValue;
		  this.rhsValue=rhs;
		  this.operator=op;
	  }
	  public String getImportance(){
		  return this.importance;
	  }
	  public String getRHS(){
		  return this.rhsValue;
	  }
	  public String getOP(){
		  return this.operator;
	  }
	  public void setImportance(String imValue){
		  this.importance=imValue;
	  }
	  public void setRHS(String rhs){
		  this.rhsValue=rhs;
	  }
	  public void setOP(String op){
		  this.operator=op;
	  }
}
class CompanyInfo{
	String name;
	int []importance=new int[3]; // you may choose another way to store importance values
	public CompanyInfo(String companyName,int[] importanceValues){
		this.name=companyName;
		this.importance=importanceValues;
	}
	public String getCompanyName(){
		return this.name;
	}
	public int[]getImportanceValue(){
		return this.importance;
	}
	public void setCompanyName(String companyName){
		this.name=companyName;
	}
	public void setImportanceValue(int[]importanceValues){
		this.importance=importanceValues;
	}	
}

الكود يستخدم الطريقة التي وضعها الأخ herch مع إضافة أجزاء أخرى مكتوبه بطريقة ليست جيدة. عليك تغيير الكود بما يناسبك و جعله بصورة أفضل ...

لمعلومات أكثر عن XPath راجع الرابط الذي أشار له الآخ herch أو راجع موقع oracle ..

ما هي الجزئية التي لم تفهمها في الكود ... فعلى الأغلب الكود واضح .

تم تعديل هذه المشاركة بواسطة YaSeenTA في 7 سبتمبر 2010 في 21:42

#17

اخي العزيز للاسف عندما عملت له كمبايلر اعطاني error ولم اعرف مالسبب

بالنسبة W1,W2.W3 هي قيم ثابتة يقوم المستخدم بادخالها في اول البرنامج او يمكننا تثبيتها في بداية البرنامج

اشكر لكم تفاعلكم

#18

لم تجب على سؤالي !!

اقتباس
اخي العزيز للاسف عندما عملت له كمبايلر اعطاني error ولم اعرف مالسبب

ضع رسالة الخطأ هنا وإلا كيف سنعلم ما المشكلة التي واجهتك ..

الكود يعمل عندي دون أي مشاكل.

بالنسبة للمعادلة , غير الكود كما يأتي :

        while (It.hasNext()) { 
            int []imValues={0,0,0};
            String imLabel = It.next();
            imValues=importanceInfo.get(imLabel).getImportanceValue();            
            System.out.println(imLabel + " -> " + imValues[0]+" , "+imValues[1]+" , "+imValues[2]); 
            int sum=W[0]*imValues[0]+W[1]*imValues[1]+W[2]*imValues[2];
            System.out.println("Sum= "+sum);
        }

أكرر عليك تغيير الكود بما يتناسب مع مشكلتك, ما قمنا به فقط وضع بداية الخيط لك ..

#19

اعتذر لك لعدم ردي على سؤالك

انا في البداية استخدمت برنامج Altova وهو برنامج جميل لكن مجاني لمدة شهر فعملت به الاسكيما

والان استخدم برنامج Eclipse وهو برنامج جميل للجافا والxml ايضا

الكود الذ كتبتة رائع لكن الخطا كان في السطر التالي

if (!value.isEmpty()) {

الان اخذت من الكود الموجود وبحسب فهمي كتبت كود وفيه اشياء ناقصة وارجو منكم ابداى ملاحضاتكم لاني جديد على الجافا ,وهي اني عملت العلاقة بين RHS وال value يساوي فقط ولااعرف كيف استطيع استدعاء المعاملات التي في OP في ملف الاكس ام ال وعمل مقارنة بواسطتها وهي (=و <=,>=)

والشي الاخر اني اريد ان استقبل الملفات الخاصة بالشركات companyFile من خارج البرنامج مثلاً كانها رساله sms اتت للجهاز .

وعندي استفسار اخر والمسامحة للاطاله

هل يمكنني بعد ان انجز البرنامج انزاله على الجوال ويشتغل علية .

package com.javabeat.tips.xpath;


import org.w3c.dom.*;

import javax.xml.xpath.*;
import javax.xml.parsers.*;

import java.io.File;
import java.io.IOException;
import org.xml.sax.SAXException;

public class mobileApp { 

  public static void main(String[] args) 
   throws ParserConfigurationException, SAXException, 
          IOException, XPathExpressionException {


	  ScoreP("p-rule1.xml",10,7,4) ;

  }

 private static void ScoreP(String companyFile,int W1,int W2,int W3)throws SAXException, ParserConfigurationException, IOException, XPathExpressionException {
  DocumentBuilderFactory factoryU = DocumentBuilderFactory.newInstance(); 
  DocumentBuilder documentBuidler1 = factoryU.newDocumentBuilder(); 
  Document doc = documentBuidler1.parse(new File("u-rule.xml"));

  XPathFactory xpathFactory = XPathFactory.newInstance(); 
  XPath xpath = xpathFactory.newXPath(); 

  DocumentBuilderFactory factoryP = DocumentBuilderFactory.newInstance(); 
  DocumentBuilder documentBuidler2 = factoryP.newDocumentBuilder(); 
  Document doc2 = documentBuidler2.parse(new File(companyFile)); 
  XPathExpression expr = xpath.compile("//RHS/text()");

  XPathExpression expr2 = xpath.compile("//root/value/text()");
  XPathExpression expression = xpath.compile("//importance/text()");


  XPathExpression exprIdP = xpath.compile("//identifier/text()");
  XPathExpression exprIdU = xpath.compile("//identifier/text()");
  XPathExpression exprDes = xpath.compile("//LHS/text()");


  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  Object result2 = expr2.evaluate(doc2, XPathConstants.NODESET);
  Object result3 = expression.evaluate(doc, XPathConstants.NODESET);

  Object resultIdU =  exprIdU.evaluate(doc, XPathConstants.NODESET);
  Object resultIdP =  exprIdP.evaluate(doc2, XPathConstants.NODESET);
  Object resultDec = exprDes.evaluate(doc, XPathConstants.NODESET);

  NodeList nodes = (NodeList) result;
  NodeList nodes2 = (NodeList) result2;
  NodeList list = (NodeList)result3;

  NodeList nodesIdU = (NodeList) resultIdU;
  NodeList nodesIdP = (NodeList) resultIdP;
  NodeList nodesDec = (NodeList) resultDec;

  String  ns;
  int x=0,y=0,z=0;

	for (int i = 0; i < nodes.getLength(); i++) {
          String s = nodes.item(i).getTextContent();
          String s2 = nodes2.item(i).getTextContent();
          String s3 = list.item(i).getTextContent();
          String NS = nodesDec.item(i).getTextContent();


         if (s.equals(s2) && s3.equalsIgnoreCase("high") && nodesIdP.item(i).getTextContent().equals(nodesIdU.item(i).getTextContent())){
      	   x++;
          	//System.out.println(s +"   equla    "+ s2);
         }else 
          	if(s.equals(s2) && s3.equalsIgnoreCase("mediam") && nodesIdP.item(i).getTextContent().equals(nodesIdU.item(i).getTextContent())){
          		y++; //System.out.println(s +"   equla    "+ s2);
          	}else if (s.equals(s2) && s3.equalsIgnoreCase("low") && nodesIdP.item(i).getTextContent().equals(nodesIdU.item(i).getTextContent())){
          		z++;
          		//System.out.println(s +"   equla    "+ s2);
          	}else

          	if (!s.equals(s2) && s3.equalsIgnoreCase("high") && nodesIdP.item(i).getTextContent().equals(nodesIdU.item(i).getTextContent())){

          		System.out.println(NS);
          	}

  }

	int sum = W1*x+W2*y+W3*z;
	System.out.println("  sum  = "+ sum );


  }


 }

الان بعد ان عملت مقارنة بين تفضيلات المستخدم مع ماتقدمة شركة واحدة ,كيف يمكنني تكرار ذلك وتخزين نتيجة كل شركة على حدة وبعد ذلك اقوم بالمرور على كل القيم الخاصة بالشركات واختيار الافضل

فمثلا

الشركة الف sum= 15

الشركة باء sum= 20

الشركة ج sum= 10

الان اريد ان اختار الشركة باء حيث هي افضل شركة للمستخدم

كل عام وانتم بالف خير وعيدكم سعيد

تم تعديل هذه المشاركة بواسطة abo_mona في 9 سبتمبر 2010 في 02:15

#20

لم تحدث لدي أي مشكلة حين تنفيذ الكود الذي كتبته اول مرة أو في كود الأخ herch أو في الكود الذي عدلته من كود الآخ herch

ارفق ملفي xml واحد لشركة وواحد للزيون الذي تطبق عليه الكود . أود التاكد من شئ ..

اقتباس

الان بعد ان عملت مقارنة بين تفضيلات المستخدم مع ماتقدمة شركة واحدة ,كيف يمكنني تكرار ذلك وتخزين نتيجة كل شركة على حدة وبعد ذلك اقوم بالمرور على كل القيم الخاصة بالشركات واختيار الافضل

فمثلا

الشركة الف sum= 15

الشركة باء sum= 20

الشركة ج sum= 10

الان اريد ان اختار الشركة باء حيث هي افضل شركة للمستخدم

وضعت فكرة لعمل لذلك في الكود الثاني ويمكن إستخدام طريقة أخرى ... يبدو أنك لم تجرب المثال ....

if (!value.isEmpty()) {

ما هو الخطأ . ضع رسالة الخطأ لنعرف سبب المشكلة ..

#21

ما وضعناه هو فقط كبداية تستطيع من خلالها تغيير الكود كما يتناسب مع المشروع الذي تريد إنجازه

هناك نقاط تعتمد على تصميم المشروع قد تحتاج بسببها تغيير الكود المكتوب في المشاركات السابقة ..

مثلاً

getCompanyInfo("customer.xml","company2.xml");

عند إستدعاء الدالة السابقة قد لا تحتاج لإعادة قراءة المعلومات من الملف customer.xml كل مرة في حالة كانت كل العمليات تجرى على هذا الملف ..

للتوضيح بامكانك جعل المستخدم يختار الملف الخاص بـالزبون من قائمة ملفات موجودة في الـ history (تم التعامل معها مسبقاً) ... وفي حالة التعامل مع ملف جديد (معلومات زبون جديدة) يتم قراءة المعلومات من جديد ..

وغير ذلك ...

#22

لقد جربت الكود السابق الذي كتبتة انت والاخ herch

انا استخدمتة مع النتبيز واشتغل كويس

وعندما جربتة في الEclipse طلع لي خطا في السطر الذي ارسلت سابقا

لقد جربت الكود الذي ارسلته وكان مكتوب بصورة رائعة من حيث التنسيق والدوال التي فية وقدجربت الكود الاخير وكانت كانت النتيجة التي تطلع غير مفهومة لي حيث كانت

p-rule2.xml -> 0 , 0 , 3

وهي ليست القيم الخاصة بالمستويات (high,low,...) المتحققه لدى الشركة.

ملف المستخدم

<?xml version="1.0" encoding="UTF-8"?>
<u-rule>
<root>
    <identifier> 1 </identifier>
    <description> send tow 3rd party </description> 
    <condition>
      <LHS> send tow 3rd party </LHS>
      <OP> = </OP>
      <RHS>yes</RHS>
    </condition>
   <importance>high</importance>
</root>
<root>
<identifier> 2 </identifier>
    <description> price sms </description> 
    <condition>
      <LHS> price sms </LHS>
      <OP> = </OP>
      <RHS>0.25</RHS>
    </condition>
 <importance>low</importance>
</root>
<root>
<identifier> 3 </identifier>
    <description> price MMS </description> 
    <condition>
      <LHS> price MMS </LHS>
      <OP> - </OP>
      <RHS>0.75</RHS>
    </condition>
    <importance>medium</importance>
</root>
<root>
<identifier> 4 </identifier>
    <description> price MMS </description> 
    <condition>
      <LHS> price video call </LHS>
      <OP> + </OP>
      <RHS>1</RHS>
    </condition>
    <importance>high</importance>
</root>
</u-rule>

ملف الشركة

<?xml version="1.0" encoding="UTF-8"?>
<u-rule>
<root>
    <identifier> 1 </identifier>
      <value>yes </value>
</root>
<root>
    <identifier> 2 </identifier>
      <value> 0.15 </value>
</root>
<root>
    <identifier> 3 </identifier>
      <value> 1 </value>
</root>
   <identifier> 4 </identifier>
      <value> 1 </value>
</root>
<root>
    <identifier> 5 </identifier>
      <value> 0.15 </value>
</root>
<root>
    <identifier> 6 </identifier>
      <value> 1 </value>
</root>
<root>
    <identifier> 7 </identifier>
      <value> yes </value>
</root>
</u-rule>

هناك الخوارزمية الخاصة بالبرنامج مع شرح لكل جزء فيها في المرفقات

ويعلم الله اني استفدت منكم استفادة كبيرة وجزاكم الله الف خير

untitled.pdf

تم تعديل هذه المشاركة بواسطة abo_mona في 9 سبتمبر 2010 في 06:07

#23

هناك خطأ بسيط - على الأغلب غير مقصود - في الملف الثاني

هنا

<identifier> 4 </identifier>

قبلها اكتب <root>

بعد التجربة كان الناتج 0,0,2 أي high القيمة 2 والبقية 0 ...

انا أستخدمEcllipse ..

لم تضع رسالة الخطأ ...

من نظرة سريعة على الخوارزمية , ستحتاج لعمل عدة تعديلات في الكود

إن وجدت وقت سأحاول كتابة الكود لكن قبل ذلك ضع محاولتك هنا

#24

فعلاً هناك خطاء في الملف الثاني

انشاء سوف احاول عمل ذلك وتجربة الكود مرة اخرى .

اريد ان اتطمن فقط

هل الخوارزمية صعبة التطبيق ام انه يمكن تنفيذها ؟؟؟؟

والسوال الثاني هل يمكن تنزيل البرنامج كتطبيق للجوال؟؟

#25

كل عام وانت بالف خير جميعا

اخواني الاعزاء ارجو منكم الرد على استفساراتي

مع خالص شكري وتقديري لكم

مواضيع مشابهة