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.

只要没有多个值,这绝对没问题。现在的问题是字段“标题”有两个值,必须用引号 ("") 括起来,如下所示。预期输出 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.

我是否需要编写另一个 xslt 才能处理这个 xml..?我可以修改现有的 xslt 本身来处理这两个 xml 变体..吗?

4

1 回答 1

1

我会更改您的输出字段模板,以便使用字段名称(属性)而不是输出值。例如传递一个field-name参数而不是field-value. 然后,您可以将有关多个值的逻辑放入该模板中。

[再想一想,你也可以通过传递字段 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 回答