如何提取具有相同名称的所有字段的值,并将它们作为列表添加到XSLT中输出字段的value属性?

时间:2014-05-30 20:04:09

标签: xml xslt xml-parsing xslt-1.0

我有一个xml文件,其中有一些字段具有相同的名称但值不同:

<field1>value1</field1>
<field1>value2</field1>

我想提取value1和value2并将其作为字符串列表添加到输出字段的value属性中:

<field value="['value1', 'value2']">...</field>

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这是grouping problem,您似乎想要按名称或local-name()对元素进行分组:

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

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="name" match="fields/*" use="local-name()"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="fields/*[generate-id() = generate-id(key('name', local-name())[1])]">
  <field>
    <xsl:attribute name="value">
      <xsl:text>[</xsl:text>
      <xsl:apply-templates select="key('name', local-name())" mode="list"/>
      <xsl:text>]</xsl:text>
    </xsl:attribute>
    <xsl:text>...</xsl:text>
  </field>
</xsl:template>

<xsl:template match="fields/*[not(generate-id() = generate-id(key('name', local-name())[1]))]"/>

<xsl:template match="fields/*" mode="list">
  <xsl:if test="position() > 1">
    <xsl:text>, </xsl:text>
  </xsl:if>
  <xsl:text>'</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>'</xsl:text>
</xsl:template>

</xsl:stylesheet>

那样输入

<fields>
<field1>value1</field1>
<field1>value2</field1>
<field2>value3</field2>
<field3>value4</field3>
<field2>value5</field2>
</fields>

转换为结果

<fields>
   <field value="['value1', 'value2']">...</field>
   <field value="['value3', 'value5']">...</field>
   <field value="['value4']">...</field>
</fields>

答案 1 :(得分:0)

假设您实际上有一个格式良好的XML带有根元素:

<fields>
    <field1>value1</field1>
    <field2>value2</field2>
</fields>

使用此样式表,您将获得所需的结果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    <xsl:template match="fields">
        <field>
            <xsl:attribute name="value">
                <xsl:text>[</xsl:text>
                <xsl:apply-templates/>
                <xsl:text>]</xsl:text>
            </xsl:attribute>
        </field>
    </xsl:template>

    <xsl:template match="fields/*">
        <xsl:text>'</xsl:text>
        <xsl:value-of select="."/>
        <xsl:text>'</xsl:text>
        <xsl:if test="position() != last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

我没有考虑field元素的内容。这种转变的结果是

<field value="['value1','value2']"/>