XSLT - 连接子值

时间:2013-09-20 08:52:09

标签: xml xslt xpath parent-child xslt-1.0

我有一个这样的示例XML:

<Record id="1">
 <Field id="1" name="Field1">
  <ListValues>
   <ListValue id="1" displayName="Bank">Bank</ListValue>
   <ListValue id="2" displayName="Personal">Personal</ListValue>
  </ListValues>
 </Field>
 <Field id="2" name="Field2"/>
</Record>

我需要将所有ID组合在一起,在输出XML中创建一个Key Field,如下所示:

<Record>
 <KeyField>1-1-12</KeyField>
</Record>

此关键字段是Record Id,Field Id(Field1 - 始终)和Field1的子节点的连续。这些子(ListValue)可以有超过100-150个值,我需要将它们组合起来形成我的关键字段(可以选择使用分隔符)。

目前,我正以这种方式执行相同的操作:

<KeyField>
 <xsl:value-of select="concat(../Record/@id,'-',Field[@name='Field1']/@id,'-', concat(Field[@name='Field1']/ListValues/ListValue/@id,Field[@name='Field1']/ListValues/ListValue[2]/@id, and so on..))"/>
</KeyField>

问题是如果我有100-150这样的值,我不能继续在KeyField元素中添加那么多。有没有一种方法可以预先计算这个并在我的关键字段元素中使用它,同样,我如何遍历所有这些值?

我正在使用XSL 1.0。

3 个答案:

答案 0 :(得分:1)

下面是一个带有命名模板的XSL 1.0解决方案,可以调用该模板来检索每条记录的关键字段。

使用的XML:

<Record id="1">
 <Field id="1" name="Field1">
  <ListValues>
   <ListValue id="1" displayName="Bank">Bank</ListValue>
   <ListValue id="2" displayName="Personal">Personal</ListValue>
   <ListValue id="3" displayName="Personal">Personal</ListValue>
   <ListValue id="4" displayName="Personal">Personal</ListValue>
   <ListValue id="5" displayName="Personal">Personal</ListValue>
   <ListValue id="6" displayName="Personal">Personal</ListValue>
   <ListValue id="7" displayName="Personal">Personal</ListValue>
   <ListValue id="8" displayName="Personal">Personal</ListValue>
  </ListValues>
 </Field>
 <Field id="2" name="Field2"/>
</Record>

使用XSLT:

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

  <xsl:template match="/">

      <xsl:for-each select="/Record">

          <xsl:element name="Record">
              <xsl:call-template name="GetKeyField">
                  <xsl:with-param name="record" select="current()" />
              </xsl:call-template>
          </xsl:element>

      </xsl:for-each>

  </xsl:template>

  <xsl:template name="GetKeyField">
      <xsl:param name="record" />
      <xsl:variable name="recordId" select="$record/@id" />
      <xsl:variable name="fieldId" select="$record/Field[@name='Field1']/@id" />
      <xsl:variable name="listValueIds">
          <xsl:for-each select="$record/Field[@name='Field1']//ListValue">
              <xsl:value-of select="@id" />
          </xsl:for-each>
      </xsl:variable>

      <xsl:element name="KeyField">
        <xsl:value-of select="normalize-space(concat($recordId, '-', $fieldId, '-', $listValueIds))" />
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>

结果:

<?xml version="1.0" encoding="UTF-8"?>
<Record><KeyField>1-1-12345678</KeyField></Record>

答案 1 :(得分:0)

未经测试:

<xsl:template match="Record">
   <xsl:element name="Keyfield">
      <xsl:value-of select="@id" />-<xsl:apply-templates />
    </xsl:element>
</xsl:template>

<xsl:template match="Field">
   <xsl:value-of select="@id" />-
</xsl:template>

<xsl:template match="ListValues><xsl:apply-templates /></xsl:template>
<xsl:template match="ListValue><xsl:value-of select="@id" /></xsl:template>

刚输入!错误的错误!

答案 2 :(得分:0)

好的,所以我在XSLT 2.0中找到了解决方案:

我创建了一个变量:

<xsl:variable name="Key_NewField">
 <xsl:value-of select="Field[@name='Field1']/ListValues/ListValue[position() &lt;= 150]/@id" />
</xsl:variable>

然后在<KeyField>元素中使用此变量($ Key_NewField)作为上一次连接的一部分。

这给了我输出(这是期望的):

<Record>
 <KeyField>1-1-1 2</KeyField>
</Record>

对于XSLT(1.0):

<xsl:variable name="Key_NewField">
 <xsl:for-each select="Field[@name = 'Field1']/ListValues/ListValue">
  <xsl:value-of select="@id"/>
 </xsl:for-each>
</xsl:variable>

给出了以下输出:

<Record>
 <KeyField>1-1-12</KeyField>
</Record>