- 浏览: 7632 次
- 性别:
- 来自: 广州
最近访客 更多访客>>
最新评论
-
昆仑山中鸟:
很好,很强大,谢谢lz~
XMLSchema(XSD)解析类 -
fireinjava:
GOOD,支持下~
XMLSchema(XSD)解析类
参考资料:http://feihu1117.iteye.com/blog/660289
二话不说,上代码。好吧。。。我承认不解析dtd而直接写成字符串是不好的,但是能抓老鼠的都是好猫嘛
package ejbModule.util; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; /** * schema解析与xml构建类<br> * 提供四个静态方法:<br> * 1、SchemaUtil.parseXSD 解析<br> * 2、SchemaUtil.createXML 创建<br> * 3、SchemaUtil.updateXML 修改<br> * 4、SchemaUtil.sortXMLNodes 排序 * @author LZY */ @SuppressWarnings("unchecked") public class SchemaUtil { /** xml修改类型:增加节点 */ public final static String UPDATETYPE_ADD = "A"; /** xml修改类型:修改节点 */ public final static String UPDATETYPE_MODIFY = "M"; /** xml修改类型:删除节点 */ public final static String UPDATETYPE_DEL = "D"; /** schema定义的节点集合 */ private static List<XSDNode> list = null; /** * 解析XSD,返回数据节点对象列表 * @param xsd xml schema * @param rootName 指定作为根节点的元素名称 * @return XSDNode元素列表 * @throws Exception */ public static List<XSDNode> parseXSD(String xsd, String rootName) throws Exception { try{ list = new ArrayList<XSDNode>(); Document doc = DocumentHelper.parseText(xsd); Element rootElement = doc.getRootElement(); String path=XMLConstants.XSD_DEFAULT_NAMESPACE+ ":element[@name=\"" + rootName + "\"]"; Element targetElement = (Element) rootElement.selectSingleNode(path); parseData(rootElement, targetElement, "/", targetElement.getPath()); return list; }catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据schema和valueMap生成xml<br> * XML生成规则:某节点的出现位置由valueMap的XPath路径(键)指定,不指定则默认按schema指定,即最少出现一次<br> * 例:"/book/column[3]/id"表示第三个/book/column下的id节点<br> * "/book/column[3]/@id"表示第三个/book/column的id属性 * @param xsd schema字符串 * @param rootName 根节点元素名 * @param valueMap "XPath路径,元素值"形式的键值对 * @return xml */ public static String createXML(String xsd,String rootName,HashMap<String, String> valueMap) { try { List<XSDNode> xsdNodeList = parseXSD(xsd,rootName); Document document = DocumentHelper.createDocument(); //先根据valueMap生成xml createNodesByValueMap(document,valueMap); //然后使用schema补充无值节点 fillNodesByXSDNodes(document,xsdNodeList); return document.asXML(); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 根据valueMap修改xml,非SchemaUtil.UPDATETYPE_ADD情况可不传入xsd<br> * XML修改规则:<br> * 1、某位置节点的增加由valueMap的XPath路径(键)及(值)指定,默认按schema指定<br> * 2、某位置节点的修改由valueMap的XPath路径(键)及(值)指定,不指定则不修改<br> * 3、某位置节点的删除由valueMap的XPath路径(键)及(值)指定,含子节点全部删除<br> * 例:"/book/column[3]/id"表示在第三个/book/column下增加id节点<br> * @param xsd schema字符串 * @param xml 修改的xml字符串 * @param updateType 1、SchemaUtil.UPDATETYPE_ADD<br> * 2、SchemaUtil.UPDATETYPE_MODIFY<br> * 3、SchemaUtil.UPDATETYPE_DEL * @param valueMap "XPath路径,元素值"形式的键值对 * @return xml */ public static String updateXML(String xsd,String xml,String updateType,HashMap<String, String> valueMap) { try { Document document = DocumentHelper.parseText(xml); if(SchemaUtil.UPDATETYPE_ADD.equals(updateType)) { List<XSDNode> xsdNodeList = parseXSD(xsd,document.getRootElement().getName()); createNodesByValueMap(document,valueMap); fillNodesByXSDNodes(document,xsdNodeList); } else if(SchemaUtil.UPDATETYPE_MODIFY.equals(updateType)) { Iterator iterator = valueMap.entrySet().iterator(); while(iterator.hasNext()) { Entry<String, String> entry = (Entry<String, String>)iterator.next(); Node node = document.selectSingleNode(entry.getKey()); if(node == null)//无此节点时先创建节点 { HashMap<String, String> tmpValueMap = new HashMap<String, String>(); tmpValueMap.put(entry.getKey(), entry.getValue()); List<XSDNode> xsdNodeList = parseXSD(xsd,document.getRootElement().getName()); createNodesByValueMap(document,tmpValueMap); fillNodesByXSDNodes(document,xsdNodeList); node = document.selectSingleNode(entry.getKey()); } node.setText(entry.getValue()); } } else if(SchemaUtil.UPDATETYPE_DEL.equals(updateType)) { List<Node> toDel = new ArrayList<Node>(); Iterator iterator = valueMap.entrySet().iterator(); while(iterator.hasNext()) { Entry<String, String> entry = (Entry<String, String>)iterator.next(); Node node = document.selectSingleNode(entry.getKey()); if(node != null) toDel.add(node); } iterator = toDel.iterator(); while(iterator.hasNext()) { Node node = (Node)iterator.next(); node.getParent().remove(node); } } return document.asXML(); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 对给出的XML,指定进行排序的节点和排序方式,进行排序<br> * 调用例:sortXMLNodes(xml, "/book/column", "order", true) * @param xml 进行排序的XML * @param xPath 进行排序的节点集,其XPath路径 * @param cmpName 排序依据值其元素XPath,可为属性或节点名称 * @param bIsAesc 升序(true)/降序(false) * @return 排序结束后的xml */ public static String sortXMLNodes(String xml,String xPath,String cmpName,boolean bIsAesc) { try { Document document = DocumentHelper.parseText(xml); List<Element> nodes = document.selectNodes(xPath,cmpName); if(bIsAesc == false) Collections.reverse(nodes); //降序 for(Element e : nodes) { Element parent = e.getParent(); parent.remove(e); parent.add(e); } return document.asXML(); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 根据ValueMap创建XML节点 * @param document xml dom * @param valueMap 值集合 * @throws Exception */ private static void createNodesByValueMap(Document document, HashMap<String, String> valueMap) throws Exception { Iterator iterator = valueMap.entrySet().iterator(); while(iterator.hasNext()) { Entry<String, String> entry = (Entry<String, String>)iterator.next(); String key = entry.getKey(); StringTokenizerCloneable tokens = new StringTokenizerCloneable(key, "/"); Element parent = document.getRootElement(); String name = tokens.nextToken(); if (parent == null) parent = document.addElement(name); Element element = null; while (tokens.hasMoreTokens()) { name = tokens.nextToken(); if (name.indexOf(':') > 0) { element = parent.element(parent.getQName(name)); } else if(name.indexOf("@") == 0) { name = name.substring(1); parent.addAttribute(name, ""); break; } else { element = parent.element(name); } if (element == null) { Pattern pa = Pattern.compile("\\[.*?\\]"); Matcher ma = pa.matcher(name); if(ma.find()) { String pos = ma.group();//位置号 name = name.substring(0,name.indexOf("["));//节点名 List<Element> elList = parent.elements(name); int iElNum = elList == null?0:elList.size(); int iPos = 0; try { iPos = Integer.valueOf(pos.substring(1,pos.length() - 1)); } catch (Exception e){iPos = iElNum;} int iDiff = iPos - iElNum;//给定位置与实际节点数的差 while(iDiff > 0) {//补充缺少节点 parent.addElement(name);//创建同名节点 iDiff --; } elList = parent.elements(name); element = elList.get(iPos - 1); } else element = parent.addElement(name); } parent = element; } document.selectSingleNode(key).setText(entry.getValue()); } } /** * 根据schema元素填充无值XML节点 * @param document xml dom * @param xsdNodeList schema元素集合 * @throws Exception */ private static void fillNodesByXSDNodes(Document document, List<XSDNode> xsdNodeList) throws Exception { for(int i=0;i < xsdNodeList.size();i++) { String path = xsdNodeList.get(i).getXPath(); StringTokenizerCloneable tokens = new StringTokenizerCloneable(path, "/"); Element parent = document.getRootElement(); String name = tokens.nextToken(); if (parent == null) parent = document.addElement(name); if (tokens.hasMoreTokens()) fillNodes(parent,tokens,tokens.nextToken()); } } /** * 递归填充无值XML节点 * @param parent 父节点 * @param tokens 记号 * @param name 当前节点名 * @throws Exception */ private static void fillNodes(Element parent,StringTokenizerCloneable tokens,String name) throws Exception { if(name.indexOf("@") == 0) { name = name.substring(1); if(parent.attribute(name) == null) parent.addAttribute(name, ""); return; } List<Element> elements = null; elements = getElements(parent,name); if (elements == null || elements.size() == 0) { parent.addElement(name); elements = getElements(parent,name); } else {//调整顺序,把已有节点放到最后 int iEl = elements.size(); for(int i=0;i < iEl;i++) { Element element = elements.get(0).createCopy(); parent.remove(elements.get(0)); parent.add(element); //修改后取回引用 elements = getElements(parent,name); } } if (tokens.hasMoreTokens()) { for(int i=0;i < elements.size();i++) { StringTokenizerCloneable clone = (StringTokenizerCloneable)tokens.clone(); fillNodes(elements.get(i), clone, clone.nextToken()); } } } /** * 获取Element集合 * @param parent 父节点 * @param name Element节点名 * @return Element集合 */ private static List<Element> getElements(Element parent,String name) throws Exception { List<Element> elements = null; if (name.indexOf(':') > 0) { elements = parent.elements(parent.getQName(name)); } else { elements = parent.elements(name); } return elements; } /** * 转换XSD的数据节点,生成XSDNode对象 * @param rootElement 根元素 * @param element 当前元素 * @param xPath 当前元素在xml中的xpath路径 * @param xsdPath 当前xsd元素在schema中的xpath路径 */ private static void parseData(Element rootElement,Element element, String xPath, String xsdPath) throws Exception { String nodeRef = element.attributeValue("ref"); if(nodeRef != null)//存在ref属性的引用情况 { Element refElement = (Element)rootElement.selectSingleNode(XMLConstants.XSD_DEFAULT_NAMESPACE + ":element[@name=\""+ nodeRef +"\"]"); xsdPath = refElement.getPath(); element = refElement; } //获取节点name属性 String nodeName = element.attributeValue("name"); //组装xml文档中节点的XPath xPath += nodeName; //组装下一个element元素的XPath String cpxXsdPath = xsdPath + "[@name=\"" + nodeName + "\"]" + "/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":complexType/"; String currentXsdPath = cpxXsdPath + XMLConstants.XSD_DEFAULT_NAMESPACE + ":sequence/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":element"; //自定义复杂类型 if (element.attribute("type") != null && element.attribute("type").getText().indexOf(XMLConstants.XSD_DEFAULT_NAMESPACE + ":") < 0) { Element typeElement = (Element)rootElement.selectSingleNode(XMLConstants.XSD_DEFAULT_NAMESPACE + ":complexType[@name=\""+ element.attribute("type").getText() +"\"]"); xsdPath = typeElement.getPath(); cpxXsdPath = xsdPath + "[@name=\"" + nodeName + "\"]" + "/"; currentXsdPath = cpxXsdPath + XMLConstants.XSD_DEFAULT_NAMESPACE + ":sequence/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":element"; } parseAttr(rootElement,cpxXsdPath,xPath); //查找该节点下所有的element元素 List<Node> elementNodes = element.selectNodes(currentXsdPath); if(elementNodes != null && elementNodes.size() > 0) {//如果下面还有element,说明不是叶子 Iterator<Node> nodes = elementNodes.iterator(); while (nodes.hasNext()) { if (!xPath.endsWith("/")) { xPath += "/"; } Element ele = (Element) nodes.next(); parseData(rootElement, ele, xPath, currentXsdPath); } } else { //获取节点类型属性 String nodeType = ""; Attribute type = element.attribute("type"); if (type != null) nodeType = type.getText(); else {//该element为叶子 String spath = xsdPath + "[@name=\"" + nodeName + "\"]/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":simpleType/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":restriction"; Element typeNode = (Element) element.selectSingleNode(spath); if (typeNode == null)//另一方式 { spath = xsdPath + "[@name=\"" + nodeName + "\"]/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":complexType/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":simpleContent/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":extension"; typeNode = (Element) element.selectSingleNode(spath); } if (typeNode != null) { Attribute base = typeNode.attribute("base"); if (base != null) nodeType = base.getText(); } } XSDNode xsdNode = new XSDNode(); xsdNode.setName(nodeName); xsdNode.setXPath(xPath); xsdNode.setType(nodeType); list.add(xsdNode); } } /** * 解析节点属性 * @param rootElement 根节点 * @param cpxXsdPath 复杂类型节点路径 */ private static void parseAttr(Element rootElement,String cpxXsdPath,String xPath) throws Exception { String attrPath1 = cpxXsdPath + XMLConstants.XSD_DEFAULT_NAMESPACE + ":attribute"; List<Element> attrList = rootElement.selectNodes(attrPath1); if(attrList != null && attrList.size() > 0) { for(int i=0;i<attrList.size();i++) { addAttr(rootElement,attrList.get(i),xPath); } } String attrPath2 = cpxXsdPath + XMLConstants.XSD_DEFAULT_NAMESPACE + ":simpleContent/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":extension/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":attribute"; attrList = rootElement.selectNodes(attrPath2); if(attrList != null && attrList.size() > 0) { for(int i=0;i<attrList.size();i++) { addAttr(rootElement,attrList.get(i),xPath); } } } /** * 把节点属性加入元素列表 * @param rootElement 根节点 * @param element 属性描述节点 * @param xPath 属性所属节点xPath */ private static void addAttr(Element rootElement,Element element,String xPath) throws Exception { String nodeRef = element.attributeValue("ref"); if(nodeRef != null)//存在ref属性的引用情况 { Element refElement = (Element)rootElement.selectSingleNode(XMLConstants.XSD_DEFAULT_NAMESPACE + ":attribute[@name=\""+ nodeRef +"\"]"); element = refElement; } String name = element.attributeValue("name"); //获取节点类型属性 String nodeType = ""; Attribute type = element.attribute("type"); if (type != null) nodeType = type.getText(); else {//该element为叶子 String spath = element.getPath() + "/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":simpleType/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":restriction"; Element typeNode = (Element) element.selectSingleNode(spath); if (typeNode == null)//另一方式 { spath = element.getPath() + "/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":complexType/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":simpleContent/" + XMLConstants.XSD_DEFAULT_NAMESPACE + ":extension"; typeNode = (Element) element.selectSingleNode(spath); } if (typeNode != null) { Attribute base = typeNode.attribute("base"); if (base != null) nodeType = base.getText(); } } XSDNode xsdNode = new XSDNode(); xsdNode.setName(name); xsdNode.setXPath(xPath + "/@" + name); xsdNode.setType(nodeType); list.add(xsdNode); } /** * xsd元素对象 */ public static class XSDNode { /** 元素名称 */ private String name; /** 元素XPath */ private String xPath; /** 元素类型 */ private String type; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getXPath() { return xPath; } public void setXPath(String path) { xPath = path; } public String getType() { return type; } public void setType(String type) { this.type = type; } } /** * xsd固定名称字符串 */ private static class XMLConstants { /** xml编码 */ public static final String ENCODING = "UTF-8"; /** xsd默认命名空间 */ public static final String XSD_DEFAULT_NAMESPACE = "xs"; /** xsd复合类型节点 */ public static final String XSD_COMPLEX_TYPE = "complexType"; /** xsd序列节点 */ public static final String XSD_SEQUENCE = "sequence"; /** xsd元素节点 */ public static final String XSD_ELEMENT = "element"; /** xsd注解节点 */ public static final String XSD_ANNOTATION = "annotation"; /** xsd注解文档节点 */ public static final String XSD_DOCUMENTATION = "documentation"; /** xsd简单类型节点 */ public static final String XSD_SIMPLE_TYPE = "simpleType"; /** xsd限制节点 */ public static final String XSD_RESTRICTION = "restriction"; /** xsd name属性 */ public static final String XSD_ATTRIBUTE_NAME = "name"; /** xsd type属性 */ public static final String XSD_ATTRIBUTE_TYPE = "type"; /** xsd base属性 */ public static final String XSD_ATTRIBUTE_base = "base"; } /** * 可复制对象的StringTokenizer类 */ private static class StringTokenizerCloneable extends StringTokenizer implements Cloneable { public StringTokenizerCloneable(String str, String delim, boolean returnDelims) { super(str,delim,returnDelims); } public StringTokenizerCloneable(String str, String delim) { super(str, delim); } public StringTokenizerCloneable(String str) { super(str); } public Object clone() { StringTokenizerCloneable o = null; try { o = (StringTokenizerCloneable)super.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); } return o; } } }
相关推荐
<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/note.xsd"> <to>George <from>John <heading>Reminder <body>Don't forget the meeting! ``` 对应的 ...
在使用`xmlschema-core-2.0.3.jar`时,开发者需要将它添加到项目的类路径中,以便在Spring Web服务上下文中使用。在Spring配置文件中,可以声明一个`WebServiceTemplate`或`Marshaller`实例,它们依赖于XML Schema ...
如果问题仍然存在,可能需要深入研究错误日志,找出具体哪个类或方法因为缺少`XmlSchema-1.4.6.jar`而抛出异常,从而确定解决策略。 总之,`XmlSchema-1.4.6.jar` 是一个用于处理XML Schema的Java库,在开发SOAP ...
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> </xs:schema> ``` 这个例子定义了一个`person`元素,包含`firstName`和`lastName`两个子元素,都是字符串类型。 2. **验证XML文档**:...
XmlSchema库则为Java开发者提供了处理这些XML Schema文档的API,使得在Java应用程序中解析、验证和生成符合XML Schema的XML文档变得容易。 在开发过程中,使用XmlSchema-1.4.7.jar可以帮助开发者实现以下功能: 1. ...
- **在应用程序中读取和创建 XML Schema**:了解如何解析和生成 XML Schema 文件对于开发基于 XML 的应用至关重要。 - **在应用程序中使用 XML Schema**:XML Schema 可以用于验证 XML 数据的有效性,确保其符合预期...
2. **XMLSchema**:这个类代表一个XML Schema定义。它可以用于验证XML文档,获取Schema中的元素、属性和其他组件的信息。 3. **XSModelGroup**:表示XML Schema中的模式组,用于组合其他模式元素,如选择(`...
这通常通过编程语言中的XML解析库来实现,如Java的JAXB或.NET Framework的XmlSchema类。解析过程中,我们会提取出XSD文件中定义的所有元素和属性,以及它们的数据类型、是否可选、最大出现次数等信息。 提取这些...
本教程将详细介绍如何使用XSD文件生成C#实体类,以便于解析XML数据和生成XML文档。 首先,我们需要一个XSD文件,它定义了XML文档的结构和数据类型。XSD文件使用元素、属性和约束来描述XML文档的结构。例如,一个...
这可以通过编程语言中的XML解析库或XML工具实现,例如Java的JAXB,.NET框架的XmlSchema类等。 10. **学习资源**:"XMLSchema.chm"这样的帮助文档通常会详细解释XML Schema的语法、用法和示例,对于初学者来说是非常...
"xmlschema-1.4.5.jar.zip"是一个包含XML Schema相关实现的Java类库,主要用于处理和验证XML文档是否符合特定的XSD规范。 在Java环境中,`xmlschema-1.4.5.jar`是一个关键组件,它提供了一系列API供开发者使用,...
XML Schema是一种用于定义XML文档结构和数据类型的语言,而xsd_API则是Eclipse平台提供的一个编程接口,允许开发者在程序中对XML Schema进行操作和解析。 XML Schema Model API提供了对XML Schema的抽象表示,允许...
JAXB允许我们根据XSD文件自动生成Java类,这样在解析XML时,可以直接将XML元素转化为Java对象,提高了开发效率。 转换过程通常包括以下步骤: 1. **理解XML文件结构**:首先,需要理解XML文件中的元素、属性及其...
标题中的"AUTOSAR_MMOD_XMLSchema.zip"指的是一个与AUTOSAR(AUTomotive Open System ARchitecture)相关的压缩包文件,它包含了MMOD(Model-based Modeling and Development)的XML Schema定义。AUTOSAR是一种全球...
1. **XmlSchema**: 这是XML Schema的根对象,用于表示整个XML Schema文档。 2. **XmlSchemaSet**: 用于存储和加载多个XML Schema,并进行验证。可以使用Add方法添加新的XML Schema。 3. **XmlSchemaValidator**: ...
XML Schema定义(XSD)使用XML语法,使得XML文档的验证和处理更加方便。在这个教程中,我们将深入探讨XML Schema的核心概念、优势以及如何在实际应用中使用。 1. XML Schema简介 XML Schema的主要目标是定义XML文档...
《使用dotnet-XmlSchemaClassGenerator从XMLSchema文件生成C#类》 在.NET开发过程中,处理XML数据是一项常见的任务。XML Schema(XSD)文件是定义XML文档结构和数据类型的规范,它允许我们对XML数据进行严格的约束...
xsd = XMLSchema('schema.xsd') xml = '<root><element>value</element></root>' # 验证XML文档 is_valid = xsd.is_valid(xml) if is_valid: print("XML文档符合XSD") else: print("XML文档不符合XSD") ``` **...