Creating a unique position counter for nodes with

2019-09-20 08:28发布

I am trying to do an XSLT transformation.

The XML input looks like this

<root>
    <row>
        <col1>John</col1>
        <col2>2</col2>
        <col3>Hello<col3>
   <row>
        <col1>John</col1>
        <col2>3</col2>
        <col3>Hello<col3>
   <row>
        <col1>Eddie</col1>
        <col2>3</col2>
        <col3>Hello<col3>

I am transforming XML data and opening it in Excel. I'm trying to create some sort of position counter in Excel. Each row indicates a person's file. Some files span multiple rows as shown above. What I want to create is a row position counter for each file. For example, John would have two rows of data in the excel sheet. I want one line to have the counter read "1" and the other line read "2". While, Eddie's position counter would only read "1".

What should I be looking at or trying to do?

标签: xml excel xslt
1条回答
迷人小祖宗
2楼-- · 2019-09-20 08:41

If your data is already sorted, you might get away without grouping it. For example, given a well-formed test input:

<root>
    <row>
        <col1>Alpha</col1>
        <col2>001</col2>
    </row>
    <row>
        <col1>Alpha</col1>
        <col2>002</col2>
    </row>
    <row>
        <col1>Alpha</col1>
        <col2>003</col2>
    </row>
    <row>
        <col1>Bravo</col1>
        <col2>004</col2>
    </row>
    <row>
        <col1>Bravo</col1>
        <col2>005</col2>
    </row>
    <row>
        <col1>Charlie</col1>
        <col2>006</col2>
    </row>
    <row>
        <col1>Delta</col1>
        <col2>007</col2>
    </row>
    <row>
        <col1>Delta</col1>
        <col2>008</col2>
    </row>
    <row>
        <col1>Delta</col1>
        <col2>009</col2>
    </row>
</root>

the following stylesheet:

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:template match="/root">
    <output>
        <xsl:for-each select="row">
            <xsl:copy>
                <col0>
                    <xsl:value-of select="count(preceding-sibling::row[col1=current()/col1])+1"/>
                </col0>
                <xsl:copy-of select="*"/>
            </xsl:copy>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

will return:

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <row>
      <col0>1</col0>
      <col1>Alpha</col1>
      <col2>001</col2>
   </row>
   <row>
      <col0>2</col0>
      <col1>Alpha</col1>
      <col2>002</col2>
   </row>
   <row>
      <col0>3</col0>
      <col1>Alpha</col1>
      <col2>003</col2>
   </row>
   <row>
      <col0>1</col0>
      <col1>Bravo</col1>
      <col2>004</col2>
   </row>
   <row>
      <col0>2</col0>
      <col1>Bravo</col1>
      <col2>005</col2>
   </row>
   <row>
      <col0>1</col0>
      <col1>Charlie</col1>
      <col2>006</col2>
   </row>
   <row>
      <col0>1</col0>
      <col1>Delta</col1>
      <col2>007</col2>
   </row>
   <row>
      <col0>2</col0>
      <col1>Delta</col1>
      <col2>008</col2>
   </row>
   <row>
      <col0>3</col0>
      <col1>Delta</col1>
      <col2>009</col2>
   </row>
</output>

Note: this is not a very fast method; if you have a very large data set, you may have to wait a bit.

查看更多
登录 后发表回答