我正在使用SaxonHE jar用于XSLT 2.0处理器,以通过XSD将元素的顺序更改为所需的序列。但没有得到理想的输出 我的xml文件是:
<param xsi:type="Bank">
<bankData name="ABC"/>
<branchAddress id="ABCB1">NY</branchAddress>
<legalAddress id="ABCL1">UK</legalAddress>
</param>
根据XSD,param标签的子元素的正确顺序是bankData,legalAddress,branchAddress。 标签参数可以包含任何类型的数据。因此,如果属性类型为“Bank”
,则应更改序列我正在使用此XSL代码来更改序列:
<xsl:variable name="bankElementSeq" as="element()*">
<bankData/><legalAddress/><branchAddress/>
</xsl:variable>
<xsl:template match="param/*">
<xsl:if test="param/@xsi:type='Bank'">
<xsl:perform-sort select="param/*">
<xsl:sort select="index-of($bankElementSeq//node-name(.), node-name(.))"/>
</xsl:perform-sort>
</xsl:if>
</xsl:template>
必需的输出是:
<param xsi:type="Bank">
<bankData name="ABC"/>
<legalAddress id="ABCL1">UK</legalAddress>
<branchAddress id="ABCB1">NY</branchAddress>
</param>
但我得到的输出为:
<param xsi:type="Bank">
</param>
未写入子元素 这可能是什么问题?
答案 0 :(得分:0)
请参阅@ MichaelKay的解决方案,以便很好地解释为什么您当前的方法不起作用。
我想建议一种略微不同的方法。它不会尝试对条目进行排序,而只是使用辅助变量来迭代而不是param
中的子标记。这应该在功能上等同于现在,但是在其他设置中可能有一些优势,在这些设置中您只想输出标签的子集。您只需在辅助变量中包含所需的标记,并将所有其他标记保留在其中。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:variable name="bankElementSeq" as="element()*">
<bankData/><legalAddress/><branchAddress/>
</xsl:variable>
<!-- the following pattern restricts the match to exactly the type of param you want to modify -->
<xsl:template match="param[@xsi:type='Bank']">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="param" select="."/>
<!-- iterate over the elements in the sorting order -->
<xsl:for-each select="$bankElementSeq">
<!-- and copy the found found by 'local-name' -->
<xsl:copy-of select="$param/*[local-name() = local-name(current())]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
让我们更详细地看一下这段代码:
<xsl:template match="param/*">
<xsl:if test="param/@xsi:type='Bank'">
<xsl:perform-sort select="param/*">
<xsl:sort select="index-of($bankElementSeq//node-name(.), node-name(.))"/>
</xsl:perform-sort>
</xsl:if>
</xsl:template>
首先,此模板依次应用于param 的每个子项。它会影响所选元素的处理方式,不会影响处理所选元素的时间。要重新排列“param”的子元素,您需要模板中的“param”元素逻辑,而不是其子元素的模板。
其次,在模板中,您有一个相对路径表达式param / @ xsi:type。这是相对于上下文节点评估的,上下文节点是“param”的子节点。所以你正在寻找一个自称为param的param的孙子。您的示例XML没有这样的孙子。你在xsl的路径表达式中重复这个错误:perform-sort / @ select。
所以你实际上可以实现你想要的东西:
<xsl:template match="param[@xsi:type='Bank']">
<xsl:perform-sort select="*">
<xsl:sort select="index-of($bankElementSeq/node-name(.), node-name(.))"/>
</xsl:perform-sort>
</xsl:template>