我需要一些帮助,如果有人感到特别慷慨...... 我需要一个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;
希望找到解决方案,并提前感谢。
我的尝试没有产生真正的输出,是
<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>
答案 0 :(得分:0)
您的尝试不起作用的原因是名称空间。当你这样做时:
<xsl:for-each select="Messages/Message1/MyAppRequest/Row">
您没有选择任何内容,因为Messages
,Message1
和MyAppRequest
位于命名空间中,需要使用绑定到相应命名空间的前缀来解决。
为了使事情更“有趣”,XML文档的作者对ns0
和Messages
使用相同的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>