如何按字段ID拆分文档?

时间:2012-06-12 13:00:01

标签: xslt

请告诉我如何按字段ID分割文件。例如,文档编号保存在行[@id=0]/field[@id=1]line[@id=0]/field[@id=2]中,line[@id>0]中保存的代码和值。

XML示例:

<document>
    <sheet id="0" name="Sheet1">
        <line id="0">
            <field id="0"><![CDATA[Code]]></field>
            <field id="1"><![CDATA[01]]></field>
            <field id="2"><![CDATA[02]]></field>
        </line>
        <line id="1">
            <field id="0"><![CDATA[9772]]></field>
            <field id="1"><![CDATA[9.0]]></field>
            <field id="2"><![CDATA[5.0]]></field>
        </line>
        <line id="5">
            <field id="0"><![CDATA[9771]]></field>
            <field id="1"><![CDATA[1.0]]></field>
            <field id="2"/>
        </line>
        <line id="1">
            <field id="0"><![CDATA[9773]]></field>
            <field id="1"><![CDATA[8.0]]></field>
            <field id="2"><![CDATA[4.0]]></field>
        </line>
    </sheet>    
</document>

如果需要结果:

<documents>
    <document>
        <header>
            <number>01</number>
        </heder>
        <line>
            <line-item>
                <lineNumber>1</lineNumber>
                <Code>9772</Code>
                <value>9.0</value>
            </line-item>
            <line-item>
                <lineNumber>2</lineNumber>
                <Code>9771</Code>
                <value>1.0</value>
            </line-item>
            <line-item>
                <lineNumber>3</lineNumber>
                <Code>9773</Code>
                <value>8.0</value>
            </line-item>
        </line>
    </document>
    <document>
        <header>
            <number>02</number>
        </heder>
        <line>
            <line-item>
                <lineNumber>1</lineNumber>
                <Code>9772</Code>
                <value>5.0</value>
            </line-item>
            <line-item>
                <lineNumber>2</lineNumber>
                <Code>9773</Code>
                <value>4.0</value>
            </line-item>
        </line>
    </document>
</documents>

转换应该适用于xsl:stylesheet version =“1.0”

1 个答案:

答案 0 :(得分:1)

试试这个......

解决方案1:程序

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

<xsl:template match="*" />

<xsl:template match="/">
 <documents>
   <xsl:apply-templates select="document/sheet/line[@id='0']/field[@id!='0']" />
 </documents>
</xsl:template>

<xsl:template match="field[@id!='0']">
 <document>
  <header>
    <number><xsl:value-of select="." /></number>
  </header>
  <line>
   <xsl:call-template name="line-item-template" >
    <xsl:with-param name="value-id"  select="@id" /> 
    <xsl:with-param name="lines"     select="../../line[@id!='0']"/> 
   </xsl:call-template>
  </line>
 </document>
</xsl:template>

<xsl:template name="line-item-template">
 <xsl:param name="value-id" /> 
 <xsl:param name="lines" /> 
 <xsl:for-each select="$lines[field[@id=$value-id]!='']" > 
  <line-item>
   <lineNumber><xsl:value-of select="format-number(position(),'00')" /></lineNumber>
   <Code><xsl:value-of select="field[@id='0']" /></Code>
   <value><xsl:value-of select="field[@id=$value-id]" /></value>
  </line-item>
  </xsl:for-each > 
</xsl:template>

</xsl:stylesheet>

..或试试这个......

解决方案2:模板o-phile

此解决方案挂钩到与输出节点相关的节点。

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

<xsl:template match="*" />

<xsl:template match="/">
 <documents>
   <xsl:apply-templates select="document/sheet/line[@id='0']/field[@id!='0']" />
 </documents>
</xsl:template>

  <xsl:template match="field[parent::line[@id='0']][@id!='0']">
 <document>
  <header>
    <number><xsl:value-of select="." /></number>
  </header>
  <line>
    <xsl:variable name="value-index" select="@id" />
    <xsl:apply-templates select="../../line[@id!='0']/field[@id=$value-index]" />
  </line>
 </document>
</xsl:template>

<xsl:template match="field[parent::line[@id!='0']][.!='']">
  <xsl:variable name="current" select="." />
  <xsl:variable name="value-index" select="@id" />
  <line-item>
   <lineNumber><xsl:value-of select="format-number( count(
       preceding::line[field[@id=$value-index]!=''] 
                      [..=$current/../..]
       ),'00')" /></lineNumber>
   <Code><xsl:value-of select="../field[@id='0']" /></Code>
   <value><xsl:value-of select="." /></value>    
  </line-item>
</xsl:template>

</xsl:stylesheet>

现在想象一下为XSLT 2.0解决这个问题。现在那会很有趣! : - )