[英]Apache XMLSchema core XSD/XML parser shows the root element as parent for all children instead of its immediate parent
I am trying to parse the XSD
using Apache XMLSchema Core
.我正在尝试使用
Apache XMLSchema Core
解析XSD
。 I am able to parse the file and store the Parent
and its Child Element
information within the HashMap
.我能够解析文件并将
Parent
元素及其Child Element
信息存储在HashMap
中。
Each Child
element is stored in the type XmlSchemaElement
which also consists of the Parent
information of that child element.每个
Child
元素都存储在XmlSchemaElement
类型中,该类型还包含该子元素的Parent
信息。 When I try to see the information related to a child element it shows the Root
element for all instead of its immediate parent.当我尝试查看与子元素相关的信息时,它会显示所有的
Root
元素而不是其直接父元素。
For example: In my XSD
, RestaurantMenu
is the Root
element and its immediate children are Food
.例如:在我的
XSD
中, RestaurantMenu
是Root
元素,其直接子元素是Food
。 Also, Food
has childrens name
, price
, calories
etc. When I see the parent element for name
I would expect it to be Food
as that's the immediate Parent but during Debug
shows the RestaurantMenu
as its parent which is a bit confusing.此外,
Food
有子name
、 price
、 calories
等。当我看到name
的父元素时,我希望它是Food
,因为那是直接父元素,但在Debug
期间将RestaurantMenu
显示为其父元素,这有点令人困惑。
I wanted to know how can I get the information related to the immediate parent for each element.我想知道如何获取与每个元素的直接父级相关的信息。
Following is my XSD
file:以下是我的
XSD
文件:
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RestaurantMenu">
<xs:complexType>
<xs:sequence>
<xs:element name="food" maxOccurs="5" minOccurs="0">
<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:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Following is the code I have which is written using the Apache XmlSchema Core XML Parser
: I am trying to Debug
at the point:以下是我使用
Apache XmlSchema Core XML Parser
编写的代码:我正在尝试Debug
:
List<XmlSchemaElement> childElements = getElementType(new QName("food"));
System.out.println(childElements.get(0));
Above code will return all the Children
element of food: name
, price
, calories
, description
, ingredients
.上面的代码将返回食物的所有
Children
元素: name
、 price
、 calories
、 description
、 ingredients
。 Then I am trying to see the parent for one of the element ie name
.然后我试图查看其中一个元素的父级,即
name
。 Following is the debug path I am taking:以下是我正在采用的调试路径:
childElements -> [0] -> namedDelegate -> parentSchema -> items -> [0] -> namedDelegate -> qName.
In this qName
I was expecting the food
as thats my immediate parent but I get the RestaurantMenu
which is my Root
xsd element.在这个
qName
中,我期待food
是我的直系父母,但我得到了RestaurantMenu
,它是我的Root
xsd 元素。
Please find the complete code below:请在下面找到完整的代码:
public class TestParser {
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(TestParser.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();
// Get all the elements based on the parent element
XmlSchemaElement childElement = xmlSchemaCollection.getElementByQName(entry.getKey());
// Call method to get all the child elements
getChildElementNames(childElement);
// Get the elements type based on choice
List<XmlSchemaElement> childElements = xsdElements.get(new QName("food"));
System.out.println(childElements.get(0));
}
// 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 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);
addChild(element.getQName(), itemElements);
// Call method recursively to get all subsequent element
getChildElementNames(itemElements);
schemaElements = new ArrayList<XmlSchemaElement>();
});
}
}
}
// Add child elements based on its parent
private 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);
}
}
Disclaimer: I am not an expert in XSModel, but I did use it once, a long time ago.免责声明:我不是 XSModel 方面的专家,但我确实使用过一次,很久以前。
The XSModel is a full and complete record of almost everything in the XSDs. XSModel 是 XSD 中几乎所有内容的完整记录。 Therefore it does contain the information that you are seeking.
因此,它确实包含您正在寻找的信息。 It may help to realise that XSModel was created for the purpose of validating XML documents - it was never intended to be a general-purpose in-memory representation of an XSD model.
可能有助于意识到 XSModel 是为了验证 XML 文档而创建的 - 它从未打算成为 XSD model 的通用内存表示。 If that's what you need then you will probably get on better with the Eclipse XSD model .
如果这就是您所需要的,那么您可能会更好地使用Eclipse XSD model 。 Either way, loading and manipulating XSD models is a minority sport and you should not expect the APIs to be perfectly documented.
无论哪种方式,加载和操作 XSD 模型都是一项少数运动,您不应期望 API 会被完美记录。
Can you please assist me in how to find an immediate parent for a child element within the Apache XMLSchema core library.
您能否帮助我在 Apache XMLSchema 核心库中找到子元素的直接父级。
When you talk about a 'child element' I think you mean either a local element declaration
or an element reference
.当您谈论“子元素”时,我认为您的意思是
local element declaration
或element reference
。 In general, both of those can have multiple parent element declarations because they can be declared within a global complex type.通常,它们都可以有多个父元素声明,因为它们可以在全局复杂类型中声明。 If that global complex type definition is used by more than one element declaration then your 'child element' will have more than one possible parent element.
如果该全局复杂类型定义被多个元素声明使用,那么您的“子元素”将具有多个可能的父元素。
After working for some time on the Apache XMLSchema Core
library in Java following is my observation.在 Java 中的
Apache XMLSchema Core
库上工作了一段时间后,以下是我的观察。
There is no way to get the immediate parent directly using the library you can get the information related to the current element and its children from the XmlSchemaElement.无法使用库直接获取直接父级,您可以从 XmlSchemaElement 获取与当前元素及其子级相关的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.