2011-08-13 110 views
6

如何從xsd生成xpath? XSD驗證xml。我在一個項目中工作,我使用java從xsd生成示例XML,然後從該XML生成xpath。如果有任何方法可以直接從xsd生成xpath,請告訴我。如何從xsd生成xpath?

+0

看來你目前的解決方案有效,你爲什麼要改變它?你是如何從XML創建XPath的? – svick

+0

我使用java代碼遍歷XML節點並從中創建xpath。 – user893096

+0

我還是不明白。該XPath的用途是什麼?你可以發表一個例子嗎? – svick

回答

0

有許多的問題,這樣的工具:

XPath表達式很少產生是一個很好的一個。沒有這樣的工具會產生超出位置信息的有意義的謂詞。

沒有一種工具(據我所知)會產生一個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