如何使用Java和XmlSchema Core解析XSD并读取所有复杂元素及其子元素 [英] How to parse XSD and read all the complex elements and its child elements using the Java and XmlSchema Core

查看:96
本文介绍了如何使用Java和XmlSchema Core解析XSD并读取所有复杂元素及其子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Apache XmlSchema Core 库来解析 XSD 文件,并获取所有元素及其子类型(数据类型,maxOccurs等).我正在遵循文档

解决方案

尝试了很多事情之后,我得以使代码正常工作.在此处发布代码可能会帮助计划使用用于XML/XSD解析的Apache XMLSchema核心库的人一个>.我知道这是多么令人沮丧,因为我们在互联网上没有此解析库的一些很好的示例.希望这会有所帮助.

基本上,此代码将解析整个 XSD 文件,并根据其父元素和子元素将元素存储在 HashMap 中.您可以获取任何XSD元素的父级,也可以获取与子级相关的信息,例如其父级等.请检查 e.getKey()+-" + String.join(,",e.getValue().stream().映射(v-> v.getQName().toString()).collect(Collectors.toList()))).collect(Collectors.toList());System.out.println(element);}//检查子元素并返回列表的方法私人静态void getChildElementNames(XmlSchemaElement element){//获取元素的类型XmlSchemaType elementType =元素!= null?element.getSchemaType():null;//确认元素是否为复杂类型if(elementType instanceof XmlSchemaComplexType){//获取与该元素关联的所有粒子类型XmlSchemaParticle allParticles =(((XmlSchemaComplexType)elementType).getParticle();//检查粒子属于哪种类型if(allParticles instanceof XmlSchemaAny){System.out.println(任何模式类型");} else if(XmlSchemaElement的allParticles实例){System.out.println(元素模式类型");} else if(XmlSchemaSequence的allParticles实例){//System.out.println("Sequence Schema Type");最终的XmlSchemaSequence xmlSchemaSequence =(XmlSchemaSequence)allParticles;最终List< XmlSchemaSequenceMember>items = xmlSchemaSequence.getItems();items.forEach((item)-> {XmlSchemaElement itemElements =(XmlSchemaElement)项目;schemaElements.add(itemElements);//System.out.println(``parent:" + element.getQName()+"-Child:" +//itemElements.getQName());//调用方法将当前元素添加为子元素addChild(element.getQName(),itemElements);//递归调用方法以获取所有后续元素getChildElementNames(itemElements);schemaElements = new ArrayList< XmlSchemaElement>();});} else if(XmlSchemaGroupRef的allParticles实例){}}}//根据其父元素添加子元素公共静态无效addChild(QName qName,XmlSchemaElement child){列表< XmlSchemaElement>值= xsdElements.get(qName);if(values == null){值=新的ArrayList< XmlSchemaElement>();}values.add(child);xsdElements.put(qName,values);}}

I am using the Apache XmlSchema Core library to parse the XSD file and get all the elements and its children type (datatype, maxOccurs, etc). I am following the documentation Apache XML SCHEMA CORE and trying to do. But after navigating to a certain point I am getting a bit confused. Can someone please guide me on how can I traverse through my XSD file and get all the elements and its child elements along with the related information?

I am able to get all the XSD information in my schema element I just want to know how can I access the child elements from my root RootFood and get its related information. Any help would be really appreciated.

I tried to continue further and this is what I have so far: The element RootFood belongs to the instance of the class XmlSchemaGroupParticle. I tried to debug the code to find the elements that are associated with my rootParticles, it has the field called items within which I have my food element items->[0]->namedDelegate->qName->localPart but when I try to add GET method on rootParticles to obtain the items then there is no such method.

The XmlSchemaParticle extends following classes: XmlSchemaAnnotated, XmlSchemaObject, and implements the interface XmlSchemaObjectBase but none of them have the field called Items.

Following is the Java code I have so far, I tried several things:

public class XMLSchemaCore {

    public static void main(String[] args) throws URISyntaxException,
        FileNotFoundException,
        UnsupportedEncodingException {
            String xsdPath = Paths.get(XMLSchemaCore.class.getClassLoader().getResource("test.xsd").toURI()).toFile().getAbsolutePath();
            String filePath = Path.of(xsdPath).toString();

            InputStream is = new FileInputStream(filePath);
            XmlSchemaCollection schemaCol = new XmlSchemaCollection();

            // Schema contain the complete XSD content which needs to be parsed
            XmlSchema schema = schemaCol.read(new StreamSource(is));
            // schema.write(System.out);
            for (Map.Entry<QName, XmlSchemaElement> entry: schema.getElements().entrySet()) {
                // Root element and its contents
                QName parentElementName = entry.getKey();
                XmlSchemaElement parentElementValues = entry.getValue();

                // Get the elements based on the Root element
                XmlSchemaElement root = schema.getElementByName(parentElementName);

                // Get the type of the root element
                XmlSchemaType type = root != null ? root.getSchemaType() : null;

                // Check if the root element is of Complex type
                if (type instanceof XmlSchemaComplexType) {
                    // Get the Particles associated with the element
                    XmlSchemaParticle rootParticles = ((XmlSchemaComplexType) type).getParticle();

                    // Check particle belongs to which type
                    if (rootParticles instanceof XmlSchemaAny) {
                        System.out.println("Any Schema Type");

                    } else if (rootParticles instanceof XmlSchemaElement) {
                        System.out.println("Element Schema Type");

                    } else if (rootParticles instanceof XmlSchemaGroupParticle) {
                        System.out.println("Group Schema Type");
                        System.out.println(rootParticles);
                        System.out.println(rootParticles);

                    } else if (rootParticles instanceof XmlSchemaGroupRef) {
                        System.out.println("Group Ref Schema Type");

                    }
                }
            }

        }

}

Following is the XSD file I have:

<xs:schema attributeFormDefault="unqualified"
    elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="RootFood">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="food">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element type="xs:string" name="name" />
                            <xs:element type="xs:string" name="price" />
                            <xs:element type="xs:string" name="description" />
                            <xs:element type="xs:short" name="calories" />
                            <xs:element name="ingredients">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element type="xs:string" name="ingredient"
                                            maxOccurs="unbounded" minOccurs="0" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

解决方案

After trying a lot of things I was able to get the code working. Posting the code here as it may help somebody who is planning to use Apache XMLSchema Core Library for XML/XSD parsing. I know how much frustrating it is as we do not have some good examples on the internet for this parsing library. Hope this helps.

Basically, this code will parse the whole XSD file and store the elements in the HashMap based on its parent and child element. You can obtain the Parent for any XSD element also you can get the information related to the child such as its parent etc. Check the XmlSchemaElement to get further details on the information for each child:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;

import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaAny;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaGroupRef;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSequenceMember;
import org.apache.ws.commons.schema.XmlSchemaType;

public class XMLSchemaCore {

    private static XmlSchemaCollection xmlSchemaCollection;
    private static Map<QName, List<XmlSchemaElement>> xsdElements = new HashMap<QName, List<XmlSchemaElement>>();
    private static List<XmlSchemaElement> schemaElements = new ArrayList<XmlSchemaElement>();

    public static void main(String[] args) throws URISyntaxException, FileNotFoundException, UnsupportedEncodingException {
        // Path for the file which is stored within the Resource folder
        String xsdPath = Paths.get(XMLSchemaCore.class.getClassLoader().getResource("test.xsd").toURI()).toFile().getAbsolutePath();
        String filePath = Path.of(xsdPath).toString();

        InputStream is = new FileInputStream(filePath);
        xmlSchemaCollection = new XmlSchemaCollection();

        // Schema contain the complete XSD content which needs to be parsed
        XmlSchema schema = xmlSchemaCollection.read(new StreamSource(is));
        // schema.write(System.out);

        // Get the root element from XSD
        Map.Entry<QName, XmlSchemaElement> entry = schema.getElements().entrySet().iterator().next();
        QName rootElement = entry.getKey();

        // Get all the elements based on the parent element
        XmlSchemaElement childElement = xmlSchemaCollection.getElementByQName(rootElement);

        // Call method to get all the child elements
        getChildElementNames(childElement);

        String element = "" + xsdElements.entrySet().stream().map(e -> e.getKey() + " -- " + String.join(", ", e.getValue().stream().map(v -> v
                            .getQName().toString()).collect(Collectors.toList()))).collect(Collectors.toList());

        System.out.println(element);
    }

    // Method to check for the child elements and return list
    private static void getChildElementNames(XmlSchemaElement element) {

        // Get the type of the element
        XmlSchemaType elementType = element != null ? element.getSchemaType() : null;

        // Confirm if the element is of Complex type
        if (elementType instanceof XmlSchemaComplexType) {
            // Get all particles associated with that element Type
            XmlSchemaParticle allParticles = ((XmlSchemaComplexType) elementType).getParticle();

            // Check particle belongs to which type
            if (allParticles instanceof XmlSchemaAny) {
                System.out.println("Any Schema Type");

            } else if (allParticles instanceof XmlSchemaElement) {
                System.out.println("Element Schema Type");

            } else if (allParticles instanceof XmlSchemaSequence) {
                // System.out.println("Sequence Schema Type");
                final XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) allParticles;
                final List<XmlSchemaSequenceMember> items = xmlSchemaSequence.getItems();
                items.forEach((item) -> {
                    XmlSchemaElement itemElements = (XmlSchemaElement) item;
                    schemaElements.add(itemElements);
                    // System.out.println(" Parent : " + element.getQName() + " -- Child : " +
                    // itemElements.getQName());
                    //Call the method to add the current element as child
                    addChild(element.getQName(), itemElements);
                    // Call method recursively to get all subsequent element
                    getChildElementNames(itemElements);
                    schemaElements = new ArrayList<XmlSchemaElement>();
                });

            } else if (allParticles instanceof XmlSchemaGroupRef) {

            }
        }
    }

    // Add child elements based on its parent
    public static void addChild(QName qName, XmlSchemaElement child) {
        List<XmlSchemaElement> values = xsdElements.get(qName);
        if (values == null) {
            values = new ArrayList<XmlSchemaElement>();
        }
        values.add(child);
        xsdElements.put(qName, values);
    }

}

这篇关于如何使用Java和XmlSchema Core解析XSD并读取所有复杂元素及其子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆