我有一个输入XML,如:
<Root>
<FirstTag>
<Attribute1>value1</Attribute1>
<Attribute2>value2</Attribute2>
<FirstTagValue>Test</FirstTagValue>
</FirstTag>
</Root>
我想用java转换它
<ns:Root xmlns:ns="http://my.comp.com/root" xmlns:ns1="http://my.comp.com/child">
<ns:FirstTag Attribute1="value1" Attribute2="value2">
<ns1:FirstTagValue>Test</ns1:FirstTagValue>
</ns:FirstTag>
</ns:Root>
我为输出XML定义了XSD。所以,基本上我想根据XSD检查输入XML标签,然后动态构建我的输出XML。
答案 0 :(得分:2)
您可以使用XSD验证XML文档是否符合其规则。
XSD本身不会将一个XML文档转换为另一个XML文档。为此,请使用XSLT。
答案 1 :(得分:0)
如果您想要从架构中使用的唯一信息是决定是将子元素转换为属性,还是将其保留为子元素,那么您可以使用Saxon中的工具(您和# 39; ll需要Saxon-EE来进行模式识别。
首先,从您的架构创建一个SCM文件(使用com.saxonica.Validate
选项运行-scmout:schema.scm
)。 SCM文件是架构组件模型的XML表示形式,它比原始源架构更易于处理。
在SCM文件中,对于像FirstTag
这样的元素,您会发现类似这样的内容:
<scm:element id="C141"
name="FirstTag"
targetNamespace="http://something"
type="C392".../>
然后你可以找到相应的类型:
<scm:complexType id="C392"
base="C344"
derivationMethod="extension"
abstract="false"
variety="mixed">
<scm:attributeUse required="false" inheritable="false" ref="C1075"/>
<scm:attributeUse required="false" inheritable="false" ref="C1076" default="no"/>
<scm:attributeUse required="false" inheritable="false" ref="C1077"/>
并且对于每个attributeUse,您将找到一个属性声明,如:
<scm:attribute id="C1075"
name="select"
type="C156".../>
所以在XSLT中,您可以编写一个函数来测试给定元素是否具有这样的给定属性(忽略名称空间,并假设$ SCM是一个包含SCM文档的全局变量):
<xsl:function name="f:elementHasAttribute" as="xs:boolean">
<xsl:param name="element" as="xs:string"/>
<xsl:param name="attribute" as="xs:string"/>
<xsl:variable name="decl" select="$SCM//scm:element[@name=$element]"/>
<xsl:variable name="type" select="$SCM//scm:complexType[@id=$decl/@type]"/>
<xsl:variable name="atts" select="
for $u in $type/scm:attributeUse return
$SCM//scm:attribute[@id=$u/@ref]"/>
<xsl:sequence select="$atts/@name = $attribute"/>
</xsl:function>
现在您可以处理这样的元素:
<xsl:template match="*">
<xsl:copy>
<xsl:variable name="attributeChildren"
select="*[f:elementHasAttribute(current()/local-name(), local-name())]"/>
<xsl:for-each select="$attributeChildren">
<xsl:attribute name="{local-name()}" select="."/>
</xsl:for-each>
<xsl:copy-of select="* except $attributeChildren"/>
</xsl:copy>
</xsl:template>
我还没有对代码进行过测试,但设计肯定会有效。