如何使用xslt将XML转换为另一个XML文件

时间:2010-06-02 15:24:18

标签: xml xslt

我输入了XML,我必须使用XSLT将其重组为另一个XML。 以下是输入文件的示例:

<?xml version="1.0" encoding="UTF-8"?>
<Report asOfDate="2010-03-31 00:00:00"
       <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010" fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK4V10" fieldValueIsNull="false" fieldValueNatural="9001HK4V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0003" fieldValueIsNull="false" fieldValueNatural="0003"/>
 <FieldValue fieldName="post_value" fieldValue="61,941.00" fieldValueIsNull="false" fieldValueNatural="61941.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_06_000_0_065_0" fieldValueIsNull="false" fieldValueNatural="r_06_000_0_065_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
    </Record>
    <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010"  fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0003" fieldValueIsNull="false" fieldValueNatural="0003"/>
 <FieldValue fieldName="post_value" fieldValue="4,157.00" fieldValueIsNull="false" fieldValueNatural="4157.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_06_570_0_070_0" fieldValueIsNull="false" fieldValueNatural="r_06_570_0_070_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
    </Record>
    <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010" fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0629" fieldValueIsNull="false" fieldValueNatural="0629"/>
 <FieldValue fieldName="post_value" fieldValue="1.00" fieldValueIsNull="false" fieldValueNatural="1.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_24_000_1_020_0" feldValueIsNull="false" fieldValueNatural="r_24_000_1_020_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
    </Record>
    <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010" fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0003" fieldValueIsNull="false" fieldValueNatural="0003"/>
 <FieldValue fieldName="post_value" fieldValue="61.00" fieldValueIsNull="false" fieldValueNatural="61.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_06_570_1_070_0" fieldValueIsNull="false" fieldValueNatural="r_06_570_1_070_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_2242_SPU" fieldValueIsNull="false" fieldValueNatural="c_2242_SPU"/>
    </Record>
    <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010" fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK1V10" fieldValueIsNull="false" fieldValueNatural="9001HK1V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0002" fieldValueIsNull="false" fieldValueNatural="0002"/>
 <FieldValue fieldName="post_value" fieldValue="3.00" fieldValueIsNull="false" fieldValueNatural="3.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_18_000_1_000_0" fieldValueIsNull="false" fieldValueNatural="r_18_000_1_000_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_9000_SPU" fieldValueIsNull="false" fieldValueNatural="c_9000_SPU"/>
    </Record>
    <Record>
 <FieldValue fieldName="rapportage_nihil" fieldValue="false" fieldValueIsNull="false" fieldValueNatural="false"/>
 <FieldValue fieldName="periode" fieldValue="31-Mar-2010" fieldValueIsNull="false" fieldValueNatural="2010-03-31 00:00:00"/>
 <FieldValue fieldName="formulierid" fieldValue="9001HK4V10" fieldValueIsNull="false" fieldValueNatural="9001HK4V10"/>
 <FieldValue fieldName="versie" fieldValue="1" fieldValueIsNull="false" fieldValueNatural="1"/>
 <FieldValue fieldName="frequentie" fieldValue="M" fieldValueIsNull="false" fieldValueNatural="M"/>
 <FieldValue fieldName="variant_type" fieldValue="Landen" fieldValueIsNull="false" fieldValueNatural="Landen"/>
 <FieldValue fieldName="value" fieldValue="0003" fieldValueIsNull="false" fieldValueNatural="0003"/>
 <FieldValue fieldName="post_value" fieldValue="2.00" fieldValueIsNull="false" fieldValueNatural="2.0"/>
 <FieldValue fieldName="cube" fieldValue="c01" fieldValueIsNull="false" fieldValueNatural="c01"/>
 <FieldValue fieldName="rij" fieldValue="r_06_000_1_040_0" fieldValueIsNull="false" fieldValueNatural="r_06_000_1_040_0"/>
 <FieldValue fieldName="kolom" fieldValue="c_2250_SPU" fieldValueIsNull="false" fieldValueNatural="c_2250_SPU"/>
        </Record>
</Report>

输出文件应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<bestand registratienummer="93391">
  <rapportage nihil="false" periode="2010-03-31" formulierid="9001HK1V10" versie="1" frequentie="M">
   <variant type="Landen" value="0003"/>
   <post value="4,157.00" cube="c01" rij="r_06_570_0_070_0" kolom="c_2250_SPU"/>
   <post value="61.00" cube="c01" rij="r_06_570_1_070_0" kolom="c_2242_SPU"/>
 </rapportage>
 <rapportage nihil="false" periode="2010-03-31" formulierid="9001HK4V10" versie="1" frequentie="M">
 <variant type="Landen" value="0002"/>
 <post value="61,941.00" cube="c01" rij="r_06_000_0_065_0" kolom="c_2250_SPU"/>
 <post value="2.00" cube="c01" rij="r_06_000_1_040_0" kolom="c_2250_SPU"/>
 </rapportage>
 <rapportage nihil="false" periode="2010-03-31" formulierid="9001HK1V10" versie="1" frequentie="M">
 <variant type="Landen" value="0629"/>
 <post value="1.00" cube="c01" rij="r_24_000_1_020_0" kolom="c_2250_SPU"/>
 </rapportage>
</bestand>

基本上我需要按变量 formulierid 对记录进行分组。 真实文件包含数千条记录,包含多种组合。 任何人都可以请我提供一个可以执行此操作的示例脚本吗?我感谢任何帮助。非常感谢。

1 个答案:

答案 0 :(得分:1)

此XSLT 1.0转换

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

  <xsl:key name="kRecordG2" match="Record" use="
    concat(
      FieldValue[@fieldName='formulierid']/@fieldValue,
      ':',
      FieldValue[@fieldName='value']/@fieldValue
    )
  " />

  <xsl:template match="Report">
    <bestand registratienummer="93391"><!-- the number is nowhere in the input -->
      <xsl:apply-templates mode="rapportage" select="
        Record[
          generate-id()
          = 
          generate-id(key('kRecordG2', 
            concat(
              FieldValue[@fieldName='formulierid']/@fieldValue,
              ':',
              FieldValue[@fieldName='value']/@fieldValue
            )
          )[1])
        ]
      " />
    </bestand>        
  </xsl:template>

  <xsl:template match="Record" mode="rapportage">
    <rapportage>
      <xsl:apply-templates select="FieldValue[@fieldName='rapportage_nihil']" />
      <xsl:apply-templates select="FieldValue[@fieldName='periode']" />
      <xsl:apply-templates select="FieldValue[@fieldName='formulierid']" />
      <xsl:apply-templates select="FieldValue[@fieldName='versie']" />
      <xsl:apply-templates select="FieldValue[@fieldName='frequentie']" />
      <variant type="Landen" value="{FieldValue[@fieldName='value']/@fieldValue}"/>
      <xsl:apply-templates mode="post" select="
        key('kRecordG2', 
          concat(
            FieldValue[@fieldName='formulierid']/@fieldValue,
            ':',
            FieldValue[@fieldName='value']/@fieldValue
          )
        )
      " />
    </rapportage>
  </xsl:template>

  <xsl:template match="Record" mode="post">
    <post>
      <xsl:apply-templates select="FieldValue[@fieldName='post_value']" />
      <xsl:apply-templates select="FieldValue[@fieldName='cube']" />
      <xsl:apply-templates select="FieldValue[@fieldName='rij']" />
      <xsl:apply-templates select="FieldValue[@fieldName='kolom']" />
    </post>
  </xsl:template>

  <xsl:template match="FieldValue">
    <xsl:variable name="attrname">
      <xsl:choose>
        <xsl:when test="@fieldName = 'rapportage_nihil'">nihil</xsl:when>
        <xsl:when test="@fieldName = 'post_value'">value</xsl:when>
        <xsl:otherwise><xsl:value-of select="@fieldName" /></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:attribute name="{$attrname}">
      <xsl:value-of select="@fieldValue" />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

给出:

<bestand registratienummer="93391">
  <rapportage nihil="false" periode="31-Mar-2010" formulierid="9001HK4V10" versie="1" frequentie="M">
    <variant type="Landen" value="0003" />
    <post value="61,941.00" cube="c01" kolom="c_2250_SPU"></post>
    <post value="2.00" cube="c01" kolom="c_2250_SPU"></post>
  </rapportage>
  <rapportage nihil="false" periode="31-Mar-2010" formulierid="9001HK1V10" versie="1" frequentie="M">
    <variant type="Landen" value="0003" />
    <post value="4,157.00" cube="c01" kolom="c_2250_SPU"></post>
    <post value="61.00" cube="c01" kolom="c_2242_SPU"></post>
  </rapportage>
  <rapportage nihil="false" periode="31-Mar-2010" formulierid="9001HK1V10" versie="1" frequentie="M">
    <variant type="Landen" value="0629" />
    <post value="1.00" cube="c01" kolom="c_2250_SPU"></post>
  </rapportage>
  <rapportage nihil="false" periode="31-Mar-2010" formulierid="9001HK1V10" versie="1" frequentie="M">
    <variant type="Landen" value="0002" />
    <post value="3.00" cube="c01" kolom="c_9000_SPU"></post>
  </rapportage>
</bestand>

我正在研究一个更优雅的版本,让我们看看我是否能找到一个......


嗯,我认为它没有比这更好,至少在XSLT 1.0中没有。通过使用额外的密钥,大输入集可能会快一点:

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

  <xsl:key name="kRecordG2" match="Record" use="
    concat(
      FieldValue[@fieldName='formulierid']/@fieldValue,
      ':',
      FieldValue[@fieldName='value']/@fieldValue
    )
  " />
  <xsl:key name="kProp" match="FieldValue" use="
    concat(generate-id(..), @fieldName)
  " />

  <xsl:template match="Report">
    <bestand registratienummer="93391"><!-- the number is nowhere in the input -->
      <xsl:apply-templates mode="rapportage" select="
        Record[
          generate-id()
          = 
          generate-id(key('kRecordG2', 
            concat(
              FieldValue[@fieldName='formulierid']/@fieldValue,
              ':',
              FieldValue[@fieldName='value']/@fieldValue
            )
          )[1])
        ]
      " />
    </bestand>
  </xsl:template>

  <xsl:template match="Record" mode="rapportage">
    <rapportage>
      <xsl:variable name="id" select="generate-id()" />
      <xsl:apply-templates select="key('kProp', concat($id, 'rapportage_nihil'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'periode'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'formulierid'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'versie'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'frequentie'))" />
      <variant type="Landen" value="{key('kProp', concat($id, 'value'))/@fieldValue}"/>
      <xsl:apply-templates mode="post" select="
        key('kRecordG2', 
          concat(
            key('kProp', concat($id, 'formulierid'))/@fieldValue,
            ':',
            key('kProp', concat($id, 'value'))/@fieldValue
          )
        )
      " />
    </rapportage>
  </xsl:template>

  <xsl:template match="Record" mode="post">
    <post>
      <xsl:variable name="id" select="generate-id()" />
      <xsl:apply-templates select="key('kProp', concat($id, 'post_value'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'cube'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'cube'))" />
      <xsl:apply-templates select="key('kProp', concat($id, 'kolom'))" />
    </post>
  </xsl:template>

  <xsl:template match="FieldValue">
    <xsl:variable name="attrname">
      <xsl:choose>
        <xsl:when test="@fieldName = 'rapportage_nihil'">nihil</xsl:when>
        <xsl:when test="@fieldName = 'post_value'">value</xsl:when>
        <xsl:otherwise><xsl:value-of select="@fieldName" /></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:attribute name="{$attrname}">
      <xsl:value-of select="@fieldValue" />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>