3

xsltを使用して次の形式のxmlデータをcsv形式に変換しようとしています。現在、特定のカスタムフィールドの複数値を出力しようとしています。これは私のxmlデータです。

<input-xml>
 <add add-value="First Name">
    <value type="string">Newbee</value>
  </add>
   <add add-value="Surname">
    <value  type="string">user1</value>
  </add>
  <add add-value="Title">
    <value type="string">Software,engineer</value>
 </add>
 <add add-value="Title">
    <value type="string">Associate level</value>
  </add>
 <add add-value="Description">
    <value type="string">This user is new to xslt.</value>
  </add>
</input-xml>

以下は、データの変換に使用しているxsltコードのスニペットです。

 <xsl:template match="input-xml">
  <!-- output the fields in order -->
    <xsl:call-template name="output-field">
        <xsl:with-param name="field-value" select="*[(@attr-name = 'First')]/value"/>
    </xsl:call-template>
    .............
    .............
    <xsl:call-template name="output-field">
        <xsl:with-param name="field-value" select="*[(@attr-name = 'Title')]/value"/>
    </xsl:call-template>
 </xsl:template>

 <xsl:template name="output-field">
    <xsl:param name="field-value"/>
    <xsl:choose>
        <xsl:when test="contains($field-value,$delimiter)">
            <!-- if the field value contains a delimiter, then enclose in quotes -->
                             <!--delimiter here is comma (,)-->
            <xsl:text>"</xsl:text>
            <xsl:value-of select="$field-value"/>
            <xsl:text>"</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <!-- otherwise output it raw -->
            <xsl:value-of select="$field-value"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template

上記のコードを使用すると、次のようにデータを出力できます。

Newbee,User1,Software engineer,This user is new to xslt.

複数の値がない限り、これは絶対に問題ありません。問題は、フィールド'Title'に2つの値があり、以下のように引用符( "")で囲む必要があることです。期待される出力csvデータ:

Newbee,User1,"|Software engineer|,|Associate level|",This user is new to xslt.

上記のコードにどのような変更を加える必要があるのか​​、さらに先に進む方法がわかりません。誰か助けてくれませんか。

@LarsH私が投稿した質問に対する以前の回答は正常に機能しています。以下のxml形式の場合、xsltが希望どおりに機能しないことがわかりました。

<input-xml>
 <add add-value="First Name">
    <value type="string">Newbee</value>
  </add>
   <add add-value="Surname">
    <value  type="string">user1</value>

 <add add-value="Title">
    <value type="string">Associate level</value>
    <value type="string">Software,engineer</value>
 </add>

 <add add-value="Description">
    <value type="string">This user is new to xslt.</value>
  </add>
</input-xml>

私が得ている出力は

Newbee,User1,Software engineerAssociate level,This user is new to xslt.

このxmlを処理できるようにするには、別のxsltを作成する必要がありますか?既存のxslt自体を変更して、両方のxmlバリアントを処理できますか?

4

1 に答える 1

1

出力フィールドテンプレートを変更して、出力に値を取得する代わりに、フィールド(属性)の名前を取得するようにします。たとえば、のfield-name代わりにパラメータを渡しますfield-value。次に、複数の値に関するロジックをそのテンプレートに入れることができます。

[考え直してみると、フィールド値* s *を既に行っていた方法で渡すことで、これを行うこともできます...渡すものがノードセットであり、必ずしも単一の値ではないことを認識するだけです。]

出力フィールドテンプレートでは、次のように言うことができます。

<xsl:template name="output-field">
 <xsl:param name="field-name"/>
 <xsl:variable name="field-values" select="*[@attr-name = $field-name]" />
 <xsl:choose>
  <xsl:when test="count($field-values) > 1">
    <xsl:text>"</xsl:text>
      <xsl:for-each select="$field-values">
        <xsl:value-of select="concat('|', ., '|')" />
        <xsl:if test="position() != last()">,</xsl:if>
       </xsl:for-each>
     <xsl:text>"</xsl:text>
   </xsl:when>
   <xsl:when test="contains($field-values[1], $delimiter)">
      ... the rest of your existing template
 </xsl:choose>
</xsl:template>

これらの詳細についてさらにサポートが必要な場合は、どれをお知らせください。

于 2013-03-12T13:23:38.047 に答える