2011-08-13 18 views
6

मैं xsd से xpath कैसे उत्पन्न कर सकता हूं? एक्सएसडी एक एक्सएमएल मान्य करता है। मैं एक प्रोजेक्ट में काम कर रहा हूं जहां मैं जावा का उपयोग कर एक्सएसडी से नमूना एक्सएमएल उत्पन्न कर रहा हूं और फिर उस एक्सएमएल से एक्सपैथ उत्पन्न कर रहा हूं। यदि xsd से सीधे xpath उत्पन्न करने का कोई तरीका है तो कृपया मुझे बताएं।xsd से xpath कैसे उत्पन्न करें?

XPath अभिव्यक्ति शायद ही कभी उत्पन्न एक अच्छा है:

+0

ऐसा लगता है कि आपका वर्तमान समाधान काम करता है, आप इसे क्यों बदलना चाहते हैं? और आप XML से XPath कैसे बना रहे हैं? – svick

+0

मैं एक्सएमएल नोड्स के माध्यम से पुनरावृत्त करने और इसके द्वारा xpath बनाने के लिए जावा कोड का उपयोग कर रहा हूं। – user893096

+0

मुझे अभी भी समझ में नहीं आता है। XPath क्या उद्देश्य करता है? क्या आप एक उदाहरण पोस्ट कर सकते हैं? एक सुपरसेट एक्सएमएल से उत्पन्न एक्स-पथ से – svick

उत्तर

0

इस तरह के उपकरणों के साथ समस्याओं का एक नंबर रहे हैं। ऐसा कोई उपकरण स्थिति की जानकारी से परे सार्थक भविष्यवाणियों का उत्पादन नहीं करेगा।

कोई उपकरण नहीं है (मेरे ज्ञान के लिए) जो एक XPath अभिव्यक्ति उत्पन्न करेगा जो चयनित नोड्स का एक सेट चुनता है।

इसके अलावा, XPath सीखने के बिना उपयोग किए जाने वाले ऐसे टूल वास्तव में हानिकारक हैं - वे अज्ञानता का समर्थन करते हैं।

मैं किताबों और अन्य संसाधनों जैसे कि निम्नलिखित का उपयोग करके XPath की गंभीर शिक्षा की अनुशंसा करता हूं।

https://stackoverflow.com/questions/339930/any-good-xslt-tutorial-book-blog-site-online/341589#341589

अधिक जानकारी के लिए निम्न जवाब देखें ..

Is there an online tester for xPath selectors?

2

इस काम का हो सकता:

import java.io.File; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Stack; 
import javax.xml.parsers.*; 

import org.xml.sax.*; 
import org.xml.sax.helpers.DefaultHandler; 

/** 
* SAX handler that creates and prints XPath expressions for each element encountered. 
* 
* The algorithm is not infallible, if elements appear on different levels in the hierarchy. 
* Something like the following is an example: 
* - <elemA/> 
* - <elemA/> 
* - <elemB/> 
* - <elemA/> 
* - <elemC> 
* -  <elemB/> 
* - </elemC> 
* 
* will report 
* 
* //elemA[0] 
* //elemA[1] 
* //elemB[0] 
* //elemA[2] 
* //elemC[0] 
* //elemC[0]/elemB[1]  (this is wrong: should be //elemC[0]/elemB[0]) 
* 
* It also ignores namespaces, and thus treats <foo:elemA> the same as <bar:elemA>. 
*/ 

public class SAXCreateXPath extends DefaultHandler { 

    // map of all encountered tags and their running count 
    private Map<String, Integer> tagCount; 
    // keep track of the succession of elements 
    private Stack<String> tags; 

    // set to the tag name of the recently closed tag 
    String lastClosedTag; 

    /** 
    * Construct the XPath expression 
    */ 
    private String getCurrentXPath() { 
     String str = "//"; 
     boolean first = true; 
     for (String tag : tags) { 
      if (first) 
       str = str + tag; 
      else 
       str = str + "/" + tag; 
      str += "["+tagCount.get(tag)+"]"; 
      first = false; 
     } 
     return str; 
    } 

    @Override 
    public void startDocument() throws SAXException { 
     tags = new Stack(); 
     tagCount = new HashMap<String, Integer>(); 
    } 

    @Override 
    public void startElement (String namespaceURI, String localName, String qName, Attributes atts) 
     throws SAXException 
    { 
     boolean isRepeatElement = false; 

     if (tagCount.get(localName) == null) { 
      tagCount.put(localName, 0); 
     } else { 
      tagCount.put(localName, 1 + tagCount.get(localName)); 
     } 

     if (lastClosedTag != null) { 
      // an element was recently closed ... 
      if (lastClosedTag.equals(localName)) { 
       // ... and it's the same as the current one 
       isRepeatElement = true; 
      } else { 
       // ... but it's different from the current one, so discard it 
       tags.pop(); 
      } 
     } 

     // if it's not the same element, add the new element and zero count to list 
     if (! isRepeatElement) { 
      tags.push(localName); 
     } 

     System.out.println(getCurrentXPath()); 
     lastClosedTag = null; 
    } 

    @Override 
    public void endElement (String uri, String localName, String qName) throws SAXException { 
     // if two tags are closed in succession (without an intermediate opening tag), 
     // then the information about the deeper nested one is discarded 
     if (lastClosedTag != null) { 
      tags.pop(); 
     } 
     lastClosedTag = localName; 
    } 

    public static void main (String[] args) throws Exception { 
     if (args.length < 1) { 
      System.err.println("Usage: SAXCreateXPath <file.xml>"); 
      System.exit(1); 
     } 

     // Create a JAXP SAXParserFactory and configure it 
     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     spf.setNamespaceAware(true); 
     spf.setValidating(false); 

     // Create a JAXP SAXParser 
     SAXParser saxParser = spf.newSAXParser(); 

     // Get the encapsulated SAX XMLReader 
     XMLReader xmlReader = saxParser.getXMLReader(); 

     // Set the ContentHandler of the XMLReader 
     xmlReader.setContentHandler(new SAXCreateXPath()); 

     String filename = args[0]; 
     String path = new File(filename).getAbsolutePath(); 
     if (File.separatorChar != '/') { 
      path = path.replace(File.separatorChar, '/'); 
     } 
     if (!path.startsWith("/")) { 
      path = "/" + path; 
     } 

     // Tell the XMLReader to parse the XML document 
     xmlReader.parse("file:"+path); 
    } 
} 
0

मैं करने के लिए एक छोटे से पुस्तकालय पर काम कर रहा है ऐसा ही करें, हालांकि बड़े और अधिक जटिल स्कीमा के लिए, ऐसे मामले हैं जिन्हें आपको केस-दर-मामले आधार पर संबोधित करने की आवश्यकता होगी (उदाहरण के लिए, फ़िल्टर कुछ नोड्स के लिए)। समाधान के विवरण के लिए https://stackoverflow.com/a/45020739/3096687 देखें।

संबंधित मुद्दे