根据子值对父节点进行排序,并根据值在节点内排序

时间:2014-02-11 15:43:37

标签: xml xslt

我需要根据子值(发票号)对x ml进行排序,然后根据它对子节点(描述)进行排序

<?xml version="1.0" encoding="UTF-8"?>
<ReportingDocumentCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<ReportingDocument>
      <ReporterID></ReporterID>
      <TransactionDate></TransactionDate>
      <InvoiceProperties>
         <InvoiceNumber>2</InvoiceNumber>
         <InvoiceLines>
            <Description>3</Description>
         </InvoiceLines>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
      </InvoiceProperties>
</ReportingDocument>
<ReportingDocument>
      <ReporterID></ReporterID>
      <TransactionDate></TransactionDate>
      <InvoiceProperties>
         <InvoiceNumber>1</InvoiceNumber>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
         <InvoiceLines>
            <Description>8</Description>
         </InvoiceLines>
      </InvoiceProperties>
</ReportingDocument>
</ReportingDocumentCollection>

转换后我需要这个代码。我试过我没有得到合适的xslt请帮帮我

<?xml version="1.0" encoding="UTF-8"?>
<ReportingDocumentCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReportingDocument>
      <ReporterID></ReporterID>
      <TransactionDate></TransactionDate>
      <InvoiceProperties>
         <InvoiceNumber>1</InvoiceNumber>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
         <InvoiceLines>
            <Description>8</Description>
         </InvoiceLines>
      </InvoiceProperties>
</ReportingDocument>
<ReportingDocument>
      <ReporterID></ReporterID>
      <TransactionDate></TransactionDate>
      <InvoiceProperties>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
         <InvoiceNumber>2</InvoiceNumber>
         <InvoiceLines>
            <Description>3</Description>
         </InvoiceLines>
      </InvoiceProperties>
</ReportingDocument>
</ReportingDocumentCollection>

2 个答案:

答案 0 :(得分:2)

使用xsl:sort并将与例外匹配的模板与简单身份转换过程分开。

您可以研究Ian的答案here并稍微调整它以满足您的需求。始终确保您的问题建立在上一个问题的解决方案之后。

<强>样式表

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

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

   <xsl:template match="ReportingDocumentCollection">
      <xsl:copy>
         <xsl:apply-templates select="ReportingDocument">
            <xsl:sort select="InvoiceProperties/InvoiceNumber" data-type="number" order="ascending"/>
         </xsl:apply-templates>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="InvoiceProperties">
      <xsl:copy>
         <xsl:apply-templates select="InvoiceNumber"/>
         <xsl:apply-templates select="InvoiceLines">
            <xsl:sort select="Description" data-type="number" order="ascending"/>
         </xsl:apply-templates>
         <xsl:apply-templates select="*[name() != 'InvoiceNumber' and name() != 'InvoiceLines']"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

<强>输出

<?xml version="1.0" encoding="UTF-8"?>
<ReportingDocumentCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <ReportingDocument>
      <ReporterID/>
      <TransactionDate/>
      <InvoiceProperties>
         <InvoiceNumber>1</InvoiceNumber>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
         <InvoiceLines>
            <Description>8</Description>
         </InvoiceLines>
      </InvoiceProperties>
   </ReportingDocument>
   <ReportingDocument>
      <ReporterID/>
      <TransactionDate/>
      <InvoiceProperties>
         <InvoiceNumber>2</InvoiceNumber>
         <InvoiceLines>
            <Description>2</Description>
         </InvoiceLines>
         <InvoiceLines>
            <Description>3</Description>
         </InvoiceLines>
      </InvoiceProperties>
   </ReportingDocument>
</ReportingDocumentCollection>

答案 1 :(得分:0)

鉴于您不想更改大部分元素,身份转换是您明智的起点。拆分成几个模板将使这更容易使用,理解和维护。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <!-- identity transform to copy input to output -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- copy input not but sort child nodes -->
    <xsl:template match="ReportingDocumentCollection">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort select="InvoiceProperties/InvoiceNumber"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <!-- copy InvoiceNumber to output first and then sort InvoiceLines elements -->
    <xsl:template match="InvoiceProperties">
        <xsl:copy>
            <xsl:apply-templates select="InvoiceNumber"/>
            <xsl:apply-templates select="InvoiceLines">
                <xsl:sort select="Description"/>

            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

将此应用于您的输入将提供几乎您的输出。我假设你不想改变InvoiceNumber元素。