XSL对bt Field1进行排序

时间:2015-06-30 17:27:02

标签: sorting xslt

我需要一些帮助,如果有人感到特别慷慨...... 我需要一个XSLT来对Field1下面的XML进行排序。我希望它很简单,但我很挣扎。 XML如下:



<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://myERP.com/xi/XI/SplitAndMerge">
	<ns0:Message1>
		<ns0:MyAppRequest xmlns:ns0="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
			<Row xmlns:ns="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
				<Field1>100</Field1>
				<Field2>11409</Field2>
				<Field3>GBA2</Field3>
				<Field4/>
				<Field5/>
				<Field6/>
				<Field8/>
				<Field7/>
			</Row>
			<Row xmlns:ns="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
				<Field1>50</Field1>
				<Field2/>
				<Field3>637281</Field3>
				<Field4>0010122587</Field4>
				<Field5>3.863</Field5>
				<Field6>KG</Field6>
				<Field8>PDISP</Field8>
				<Field7>local-LOTEND</Field7>
			</Row>
			<Row xmlns:ns="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
				<Field1>51</Field1>
				<Field2>1000041393</Field2>
				<Field3>637281</Field3>
				<Field4>0010122587</Field4>
				<Field5>3.863</Field5>
				<Field6>KG</Field6>
				<Field8>PDISP</Field8>
				<Field7>Joe.Bloggs</Field7>
			</Row>
			<Row xmlns:ns="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
				<Field1>99</Field1>
				<Field2>4</Field2>
				<Field3/>
				<Field4/>
				<Field5/>
				<Field6/>
				<Field8/>
				<Field7/>
			</Row>
		</ns0:MyAppRequest>
	</ns0:Message1>
</ns0:Messages>
&#13;
&#13;
&#13;

希望找到解决方案,并提前感谢。

我的尝试没有产生真正的输出,是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://myERP.com/xi/XI/SplitAndMerge">
<xsl:template match="/">
    <ns0:Messages xmlns:ns0="http://myERP.com/xi/XI/SplitAndMerge">
        <ns0:Message1>
                <ns0:MyAppRequest xmlns:ns0="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
                    <xsl:for-each select="Messages/Message1/MyAppRequest/Row">
                        <xsl:sort select="Field1"/>
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
                </ns0:MyAppRequest>
            </ns0:Message1>
    </ns0:Messages>
</xsl:template>
<xsl:template match="/ns0:MyAppRequest">
    <xsl:copy-of select="."/>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

您的尝试不起作用的原因是名称空间。当你这样做时:

<xsl:for-each select="Messages/Message1/MyAppRequest/Row">

您没有选择任何内容,因为MessagesMessage1MyAppRequest位于命名空间中,需要使用绑定到相应命名空间的前缀来解决。

为了使事情更“有趣”,XML文档的作者对ns0Messages使用相同的MyAppRequest前缀,即使它们的名称空间不同。你可以先看到我们:

<ns0:Messages xmlns:ns0="http://myERP.com/xi/XI/SplitAndMerge">

但是当我们到达MyAppRequest时,ns0前缀被重新定义:

<ns0:MyAppRequest xmlns:ns0="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">

如何解决这个问题:

您可以采取简单的方法并替换:

<xsl:for-each select="Messages/Message1/MyAppRequest/Row">

使用:

<xsl:for-each select="//Row">

一个更有效的解决方案是避免使用//运算符并明确地列出包装器元素,但仍然只使用*通配符引用命名空间问题。

您需要注意的另一个问题是默认排序顺序是字母顺序,而Field1数据似乎是数字。

看看这是否适合你:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <ns0:Messages xmlns:ns0="http://myERP.com/xi/XI/SplitAndMerge">
        <ns0:Message1>
            <ns0:MyAppRequest xmlns:ns0="urn:Acme.com:GLOBAL:SAPERP:local:MyApp">
                    <xsl:for-each select="*/*/*/Row">
                        <xsl:sort select="Field1" data-type="number" order="ascending"/>
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
            </ns0:MyAppRequest>
        </ns0:Message1>
    </ns0:Messages>
</xsl:template>

</xsl:stylesheet>