如何对这个XML进行排序?

时间:2014-08-26 03:26:31

标签: xml xslt xpath

这是我想要排序的XML:

<?xml version="1.0" encoding="utf-8"?>
<Proposal>
  <MobileKey>test string</MobileKey>
  <RevisionNumber>9</RevisionNumber>
  <CreationDate>2014-04-30T13:21:00</CreationDate>
  <ProposalDueDate>test string</ProposalDueDate>
  <ProposalJobs>
    <ProposalID>56</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
  <ProposalJobs>
    <ProposalID>42</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
  <ProposalJobs>
    <ProposalID>21</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
</Proposal>

输出应该是(按ProposalID排序):

<?xml version="1.0" encoding="utf-8"?>
<Proposal>
  <MobileKey>test string</MobileKey>
  <RevisionNumber>9</RevisionNumber>
  <CreationDate>2014-04-30T13:21:00</CreationDate>
  <ProposalDueDate>test string</ProposalDueDate>
  <ProposalJobs>
    <ProposalID>21</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
  <ProposalJobs>
    <ProposalID>42</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
  <ProposalJobs>
    <ProposalID>56</ProposalID>
    <ProposalRevision>9</ProposalRevision>
    <ProposalJobNumber>9</ProposalJobNumber>
    <ServiceLine>test string</ServiceLine>
    <SubServiceLine>test string</SubServiceLine>
  </ProposalJobs>
</Proposal>

我使用了以下XSLT。它正确地进行排序,但删除除Proposal节点之外的ProposalJobs的所有子元素。请帮帮我:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="Proposal">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="ProposalJobs">
        <xsl:sort select="ProposalID"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

3 个答案:

答案 0 :(得分:3)

改变这个:

<xsl:apply-templates select="ProposalJobs">
    <xsl:sort select="ProposalID"/>
</xsl:apply-templates>

为:

<xsl:apply-templates select="*">
    <xsl:sort select="ProposalID"/>
</xsl:apply-templates>

或者,添加:

<xsl:apply-templates select="*[not(self::ProposalJobs)]"/>

就在之前:

<xsl:apply-templates select="ProposalJobs">
    <xsl:sort select="ProposalID"/>
</xsl:apply-templates>

与您的问题无关,但您应该更改此内容:

<xsl:sort select="ProposalID"/>

为:

<xsl:sort select="ProposalID" data-type="number"/>

否则ProposalID#101将在#21之前出现。


编辑:

要保留内部“块”的顺序,请使用:

<xsl:template match="Proposal">   
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(preceding-sibling::ProposalJobs)]"/>
        <xsl:apply-templates select="ProposalJobs">
            <xsl:sort select="ProposalID" data-type="number"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="node()[preceding-sibling::ProposalJobs]"/>
    </xsl:copy>  
</xsl:template>

答案 1 :(得分:1)

你可以这样做。我已经过测试并且工作正常。

<xsl:template match="Proposal">
    <xsl:copy>
     <xsl:apply-templates select="@*|node()[not(self::ProposalJobs)]" />
      <xsl:apply-templates select="ProposalJobs">
        <xsl:sort select="ProposalID"/>
      </xsl:apply-templates>

    </xsl:copy>
 </xsl:template>

答案 2 :(得分:1)

使用:

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

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Proposal">   
    <xsl:copy>
      <xsl:apply-templates select="node()[not(self::ProposalJobs)]|@*"/>
      <xsl:apply-templates select="ProposalJobs">
        <xsl:sort select="ProposalID"/>
      </xsl:apply-templates>
    </xsl:copy>   

  </xsl:template>

</xsl:stylesheet>