2

私はこのxmlを持っています:

<root>
    <row>
        <number>1001461</number>
        <unit>CAN</unit>
    </row>
    <row>
        <number>1001462</number>
        <unit>KG</unit>
    </row>
</root>

私のXslt:

<?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 method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202" />


  <xsl:template match="@* | node()">
      <DocumentElement>
          <xsl:apply-templates>
            <xsl:with-param name="primarykey" select="position()"/>
          </xsl:apply-templates>
      </DocumentElement>
    </xsl:template>

  <xsl:template match="row" name="trow">
    <xsl:param name="primarykey"/>
    <xsl:for-each select="*">
      <SaveDataTable>
        <KeyName>
          <xsl:value-of select="name()"/>
        </KeyName>
        <KeyValue>
          <xsl:value-of select="."/>
        </KeyValue>
        <PrimaryKey>
          <xsl:value-of select="concat('-',$primarykey)"/>
        </PrimaryKey>
        <FormId>
          <xsl:value-of select="$formid"/>
        </FormId>
      </SaveDataTable>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

期待される出力:(最初の2つ<PrimaryKey>は-1で、次の2つは-2であることに注意してください。これが、私が必要とする方法です)

<DocumentElement>
    <SaveDataTable>
        <KeyName>number</KeyName>
        <KeyValue>1001461</KeyValue>
        <PrimaryKey>-1</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>unit</KeyName>
        <KeyValue>CAN</KeyValue>
        <PrimaryKey>-1</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>number</KeyName>
        <KeyValue>1001462</KeyValue>
        <PrimaryKey>-2</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>unit</KeyName>
        <KeyValue>KG</KeyValue>
        <PrimaryKey>-2</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
</DocumentElement>

基本的に、すべて<row>...</row><PrimaryKey>-1</PrimaryKey>shouldが1ずつデクリメントされますが、それは発生していません。すべての<PrimaryKey>要素の値は、-1、-2などではなく-1になります。

===========================================

更新:私はそれを少し動作させますが、それが効率的かどうかはわかりません。

動作中のxslt(改善が必要な場合があります):

<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202"/>
    <xsl:template match="@* | node()">
        <DocumentElement>
            <xsl:for-each select="row">
                <xsl:call-template name="trow">
                    <xsl:with-param name="primarykey" select="position()"/>
                </xsl:call-template>
            </xsl:for-each>
        </DocumentElement>
    </xsl:template>
    <xsl:template name="trow">
        <xsl:param name="primarykey"/>
        <xsl:for-each select="*">
            <SaveDataTable>
                <KeyName>
                    <xsl:value-of select="name()"/>
                </KeyName>
                <KeyValue>
                    <xsl:value-of select="."/>
                </KeyValue>
                <PrimaryKey>
                    <xsl:value-of select="concat('-',$primarykey)"/>
                </PrimaryKey>
                <FormId>
                    <xsl:value-of select="$formid"/>
                </FormId>
            </SaveDataTable>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
4

3 に答える 3

2

別のアプローチ(「プル」スタイルではなく「プッシュ」スタイル)は、処理をテンプレートに分割します。

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

    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202"/>

ドキュメント全体の結果をでラップしますDocumentElement

    <xsl:template match="/">
        <DocumentElement>
          <xsl:apply-templates/>
        </DocumentElement>
    </xsl:template>

行ごとに、その位置番号を取得します。テキストノードを数えたくないという理由ではxsl:numberなく、を使用します。position()

    <xsl:template match="row" priority="10">
      <xsl:variable name="pos">
        <xsl:number count="row" level="single"/>
      </xsl:variable>
      <SaveDataTable>
        <xsl:apply-templates>
          <xsl:with-param name="pkey" select="-1 * $pos"/>
        </xsl:apply-templates>
      </SaveDataTable>
    </xsl:template>

row要素の各子で、SaveDataTableキー名、キー値、主キー、およびフォームIDを含む要素を発行します。

    <xsl:template match="row/*">
      <xsl:param name="pkey"/>
      <KeyName>
        <xsl:value-of select="name()"/>
      </KeyName>
      <KeyValue>
        <xsl:value-of select="."/>
      </KeyValue>
      <PrimaryKey>
        <xsl:value-of select="$pkey"/>
      </PrimaryKey>
      <FormId>
        <xsl:value-of select="$formid"/>
      </FormId>
    </xsl:template>
</xsl:stylesheet>
于 2012-08-22T00:29:21.403 に答える
0

このソリューションを試すことはできますが、効率が悪いと思います。

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

  <xsl:param name="formid" select="60202"/>

  <xsl:template match="/root">
    <DocumentElement>
      <xsl:apply-templates select="row/*"/>
    </DocumentElement>
  </xsl:template>

  <xsl:template match="*">
    <SaveDataTable>
      <KeyName>
        <xsl:value-of select="name()"/>
      </KeyName>
      <KeyValue>
        <xsl:value-of select="."/>
      </KeyValue>
      <PrimaryKey>
        <xsl:value-of select="-1 * (count(../preceding-sibling::row) + 1)"/>
      </PrimaryKey>
      <FormId>
        <xsl:value-of select="$formid"/>
      </FormId>
    </SaveDataTable>
  </xsl:template>
</xsl:stylesheet>
于 2012-08-21T22:41:00.423 に答える
0

プッシュスタイルのソリューション-CMSperberg-McQueenのソリューションと似ていますが、noxsl:numberが計算され、位置がパラメーターとして渡されるため、おそらくわずかに効率的です。

priorityもう1つの違いは、テンプレートで属性を指定する必要がないことです。

また、-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:param name="pFormid" select="60202"/>

        <xsl:template match="/*">
            <DocumentElement>
                <xsl:apply-templates/>
            </DocumentElement>
        </xsl:template>

        <xsl:template match="row">
            <xsl:apply-templates select="*">
             <xsl:with-param name="pPos" select="position()"/>
            </xsl:apply-templates>
        </xsl:template>

        <xsl:template match="row/*">
          <xsl:param name="pPos"/>

            <SaveDataTable>
                    <KeyName>
                        <xsl:value-of select="name()"/>
                    </KeyName>
                    <KeyValue>
                        <xsl:value-of select="."/>
                    </KeyValue>
                    <PrimaryKey>
                        <xsl:value-of select="-$pPos"/>
                    </PrimaryKey>
                    <FormId>
                        <xsl:value-of select="$pFormid"/>
                    </FormId>
                </SaveDataTable>
        </xsl:template>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合

<root>
    <row>
        <number>1001461</number>
        <unit>CAN</unit>
    </row>
    <row>
        <number>1001462</number>
        <unit>KG</unit>
    </row>
</root>

必要な正しい結果が生成されます:

<DocumentElement>
   <SaveDataTable>
      <KeyName>number</KeyName>
      <KeyValue>1001461</KeyValue>
      <PrimaryKey>-1</PrimaryKey>
      <FormId>60202</FormId>
   </SaveDataTable>
   <SaveDataTable>
      <KeyName>unit</KeyName>
      <KeyValue>CAN</KeyValue>
      <PrimaryKey>-1</PrimaryKey>
      <FormId>60202</FormId>
   </SaveDataTable>
   <SaveDataTable>
      <KeyName>number</KeyName>
      <KeyValue>1001462</KeyValue>
      <PrimaryKey>-2</PrimaryKey>
      <FormId>60202</FormId>
   </SaveDataTable>
   <SaveDataTable>
      <KeyName>unit</KeyName>
      <KeyValue>KG</KeyValue>
      <PrimaryKey>-2</PrimaryKey>
      <FormId>60202</FormId>
   </SaveDataTable>
</DocumentElement>
于 2012-08-22T05:01:39.583 に答える