如何使用 Java 和 XmlSchema Core 解析 XSD 并读取所有复杂元素及其子元素

Posted

技术标签:

【中文标题】如何使用 Java 和 XmlSchema Core 解析 XSD 并读取所有复杂元素及其子元素【英文标题】:How to parse XSD and read all the complex elements and its child elements using the Java and XmlSchema Core 【发布时间】:2021-06-25 15:23:08 【问题描述】:

我正在使用Apache XmlSchema Core 库来解析XSD 文件并获取所有元素及其子类型(数据类型、maxOccurs 等)。我正在关注文档Apache XML SCHEMA CORE 并尝试这样做。但是在导航到某个点之后,我有点困惑。有人可以指导我如何遍历我的XSD 文件并获取所有元素及其子元素以及相关信息吗?

我能够在我的schema 元素中获取所有 XSD 信息我只想知道如何从我的根 RootFood 访问子元素并获取其相关信息。任何帮助将不胜感激。

我试图继续前进,这就是我目前所拥有的: 元素RootFood 属于类XmlSchemaGroupParticle 的实例。我试图调试代码以查找与我的rootParticles 关联的元素,它有一个名为items 的字段,其中我有我的food 元素items->[0]->namedDelegate->qName->localPart 但是当我尝试添加GET 方法时rootParticles获取items则没有这种方法。

XmlSchemaParticle 扩展了以下类:XmlSchemaAnnotatedXmlSchemaObject,并实现了接口XmlSchemaObjectBase,但它们都没有名为Items 的字段。

以下是我到目前为止的Java代码,我尝试了几件事:

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");

                    
                
            

        


以下是我拥有的XSD 文件:

<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>

【问题讨论】:

终于,经过多次尝试,我能够做到。请在下面找到代码。 【参考方案1】:

在尝试了很多事情之后,我能够让代码正常工作。在此处发布代码,因为它可能对计划使用 Apache XMLSchema Core Library for XML/XSD parsing 的人有所帮助。我知道这是多么令人沮丧,因为我们在互联网上没有这个解析库的一些好的例子。希望这会有所帮助。

基本上,这段代码将解析整个XSD 文件并根据其父元素和子元素将元素存储在HashMap 中。您可以获取任何 XSD 元素的父级,也可以获取与子级相关的信息,例如其父级等。查看XmlSchemaElement 以获取有关每个子级信息的更多详细信息:

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 并读取所有复杂元素及其子元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在生产环境中在 Reactjs 中配置 COR

Testing.Fakes异常:无法从COR_PROFILER_PATH和COR_PROFILER环境变量解析探查器路径

R使用笔记:相关系数:cor.test();corr.test();rcorr()

Axis2错误 - java.lang.NoClassDefFoundError:org / apache / ws / commons / schema / XmlSchema

R语言使用cov函数计算矩阵或者dataframe数据变量之间的协方差cor函数计算相关性cor函数通过method参数指定相关性相关性计算方法Pearson,Spearman, Kendall

R语言使用cov函数计算矩阵或者dataframe数据变量之间的协方差cor函数计算相关性cor函数通过method参数指定相关性相关性计算方法Pearson,Spearman, Kendall