简体   繁体   English

如何对节点元素重新排序,使其与xsd:sequence顺序匹配?

[英]How to reorder node elements such that they match an xsd:sequence order?

Is there any way to reorder elements in a Node objects such that they match an xsd:sequence order? 有什么方法可以对Node对象中的元素进行重新排序,使其与xsd:sequence顺序匹配? I've read through the docs for Node.normalize , but it doesn't seem to perform that function. 我已经阅读了Node.normalize的文档,但似乎没有执行该功能。 Is there something else that can be done? 还有什么可以做的吗?

I believe that it can be done with XSLT, but it would sound like an overly convoluted solution to use XSLT, and a special java-xlst parser to perform the manipulation as opposed to having something native in java. 我相信可以使用XSLT来完成此操作,但这听起来像是使用XSLT的解决方案太复杂了,并且使用特殊的java-xlst解析器来执行操作,而不是使用Java本地的东西。

Or would I actually need to code a complex function to do the processing for me? 还是我实际上需要编写一个复杂的函数来为我做处理?

If I read your question correctly, what you want is rather a "magical" (as in a simple) way of getting nodes re-arranged according to an external XSD, as opposed to a way to move nodes around using some XML API. 如果我正确地理解了您的问题,那么您想要的是一种“神奇的”(如简单的方式)根据外部XSD重新安排节点,而不是使用一些XML API来移动节点的方式。

If true, then I am not aware of any API that provides a generic way to achieve such a thing. 如果为true,则我不知道有任何API提供了实现此类问题的通用方法。 It is also not a trivial piece of programming, given the complexity of the content models XSD is able to describe. 考虑到XSD能够描述的内容模型的复杂性,它也不是一件容易的事。

It is also, under very simple circumstances, virtually impossible to solve. 在非常简单的情况下,实际上也无法解决。 Think of this very simple example: imagine a content model made up of two choices, i) sequence a - b - c , ii) sequence b - c - a. 考虑一个非常简单的示例:想象一个由两个选择组成的内容模型,即i)序列a-b-c,ii)序列b-c-a。 The XML content comes in the order c - b - a (as per your requirement, you want to take in invalid XML, and make it valid). XML内容按c-b-a的顺序排列(根据您的要求,您要采用无效的XML并将其设为有效)。 In this example, which is the right way to do it? 在此示例中,哪种方法是正确的?

Of course, I am not saying this is your scenario. 当然,我并不是说这是您的情况。 I am simply trying to point out why no one, as far as I know, has come up with a solution to such a problem. 我只是想指出为什么据我所知没有人提出解决这一问题的办法。

If your content model under the sequence is rather trivial, thus allowing for an unambiguous way of solving it irrespective of the sequence in which your XML arrives, or if the XML content comes in a known, but wrong way, all the time, then you have to code it using your preferred approach to XML manipulation - but I would suggest, don't try to make it generic, it is just going down the rabbit hole ;).... 如果序列下的内容模型非常琐碎,因此无论您的XML到达的顺序如何,都可以采用明确的方式来解决它,或者如果XML内容始终以已知但错误的方式出现,那么您必须使用首选的XML操作方法对其进行编码-但我建议,不要尝试使其通用,这只是在钻空洞;)....

If you only have xs:sequence to worry about, and not choice/repetition, and so long as the schema isn't written to use lots of complex features like named model groups and substitution groups and wildcards, then it shouldn't be too difficult, at any rate if you use XSLT 2.0 or XQuery and forget about trying to code it in Java. 如果您只需要担心xs:sequence而不是选择/重复,并且只要模式不编写为使用很多复杂的功能(例如命名模型组,替换组和通配符),那么它也不必无论如何,如果您使用XSLT 2.0或XQuery却忘记尝试使用Java编写代码,无论如何都很难。 If the variable $seq is an xs:sequence element, then the sort key for an element named $E is "count($x/xs:element[(@name|@ref)=$E]/preceding-sibling::*", so you can just plug this expression into an xsl:sort as 如果变量$ seq是xs:sequence元素,则名为$ E的元素的排序键为“ count($ x / xs:element [(@ name | @ref)= $ E] / preceding-sibling ::: *”,因此您只需将此表达式插入xsl:sort中即可

<xsl:for-each select="*">
  <xsl:sort select="count($seq/xs:element[(@name|@ref)=local-name(current())]/preceding-sibling::*"/>
  ...
</xsl:for-each>

Probably needs a bit of finessing for namespaces or other things you might encounter, but you get the idea. 可能需要对名称空间或您可能遇到的其他问题进行一些细化,但是您明白了。

You can manipulate XML directly in Java using the following packages: 您可以使用以下软件包在Java中直接操作XML:

import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;

You'll need to put an XML parser such as saxon ( see http://saxon.sourceforge.net/ ) on your classpath 您需要在类路径上放置诸如saxon之类的XML解析器(请参阅http://saxon.sourceforge.net/ )。

You can manipulate the XML 'by hand', reading bits of the input document and creating the required output document or you can write an xslt style sheet and use it to transform the document straight from your Java code. 您可以“手动”操作XML,读取输入文档的一部分并创建所需的输出文档,或者可以编写xslt样式表并将其用于直接从Java代码转换文档。

Try here for a starting point: 试试这里作为起点:

http://oreilly.com/catalog/javaxslt/chapter/ch05.html http://oreilly.com/catalog/javaxslt/chapter/ch05.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM