How to create xpath from xsd?

How can i create xpath from xsd? XSD validates xml. I work in a project where I create an XML sample from xsd using java and then generate an xpath from this XML. If there is a way to generate xpath directly from xsd, please let me know.

+6
source share
3 answers

There are a number of problems with such tools:

An XPath expression created rarely is a good one. No such tool will create meaningful predicates beyond location information.

There is no tool (as far as I know) that would generate an XPath expression that accurately selects a set of selected nodes.

In addition, tools that are used without XPath training are really harmful — they support ignorance.

I would recommend seriously exploring XPath using books and other resources such as the following.

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

See the following answer for more information.

Is there an online tester for xPath selectors?

0
source

This may be useful:

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 the same as the current one isRepeatElement = true; } else { // ... but it different from the current one, so discard it tags.pop(); } } // if it 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); } } 
+2
source

I am working on a small library to do this, although for larger and more complex circuits there are problems that you will need to solve in each case (for example, filters for specific nodes). For a description of the solution, see fooobar.com/questions/894981 / ....

0
source

Source: https://habr.com/ru/post/894980/


All Articles