如何重新排序节点元素,使它们匹配xsd:sequence顺序?

时间:2012-01-25 17:16:44

标签: java xslt xsd jaxb sequence

有没有办法重新排序Node对象中的元素,使它们与xsd:sequence顺序匹配?我已经阅读了Node.normalize的文档,但它似乎没有执行该功能。还有其他事情可以做吗?

我相信它可以通过XSLT来完成,但它听起来像是一个过于复杂的解决方案来使用XSLT,并且一个特殊的java-xlst解析器来执行操作,而不是在java中使用本机。

或者我真的需要编写一个复杂的函数来为我做处理吗?

3 个答案:

答案 0 :(得分:3)

如果我正确地阅读了你的问题,那么你想要的是一种“神奇的”(如简单的方式)根据外部XSD重新排列节点的方式,而不是使用一些XML移动节点的方法API。

如果是,那么我不知道任何API提供了实现这种事情的通用方法。考虑到XSD能够描述的内容模型的复杂性,它也不是一个简单的编程。

在非常简单的情况下,它也几乎不可能解决。想想这个非常简单的例子:想象一个由两个选择组成的内容模型,i)序列a - b - c,ii)序列b - c - a。 XML内容按顺序c-b-a(根据您的要求,您希望获取无效的XML,并使其有效)。在这个例子中,这是正确的方法吗?

当然,我不是说这是你的情景。我只是想指出为什么没有人,据我所知,已经找到了解决这个问题的方法。

如果序列下的内容模型相当简单,那么无论XML到达的顺序如何,或者XML内容是否以已知但错误的方式出现,都可以采用明确的方式解决它,那么你必须使用你喜欢的XML操作方法对它进行编码 - 但我建议,不要试图让它变得通用,它只是在兔子洞里走下去;)....

答案 1 :(得分:2)

如果您只有xs:序列需要担心,而不是选择/重复,并且只要架构没有被编写为使用许多复杂的功能,如命名模型组和替换组和通配符,那么它应该'无论如何,如果你使用XSLT 2.0或XQuery而忘记尝试用Java编写代码,那就太难了。如果变量$ seq是xs:sequence元素,那么名为$ E的元素的排序键是“count($ x / xs:element [(@ name | @ref)= $ E] / preceding-sibling :: *“,所以你可以将这个表达式插入xsl:sort as

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

可能需要对命名空间或其他可能遇到的事情进行一些调整,但是你明白了。

答案 2 :(得分:-1)

您可以使用以下包直接在Java中操作XML:

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

您需要在类路径上放置一个XML解析器,例如saxon(请参阅http://saxon.sourceforge.net/

您可以手动操作XML,读取输入文档的位并创建所需的输出文档,或者您可以编写xslt样式表并使用它直接从Java代码转换文档。

在此尝试一个起点:

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