在同一for-each循环中循环搜索结果

时间:2014-07-11 03:48:52

标签: loops xslt

我正在使用XSLT 1.0。在地址节点中循环时,我需要读取当前节点并从下一个节点检索数据。是否可以使用我使用的代码执行此操作,还是需要在循环中执行循环?好心劝告。非常感谢。

我使用的代码是:

<Data>
 <xsl:for-each select="Record/Address>
 <xsl:if test="Objtyp='H'">
 <xsl:variable name="objkeyH" select="Objkey"/>
  <Location>
    <Region><xsl:value-of select="description"/></Region>
    <houseNumber><xsl:value-of select="houseNumber[parentID=$objkeyH]"/></houseNumber>
    <Street><xsl:value-of select="Street[parentID=$objkeyH]"/></Street>
    <Postcode><xsl:value-of select="Postcode[parentID=$objkeyH]"/></Postcode>
    <City><xsl:value-of select="City[parentID=$objkeyH]"/></City>     
  </Location>
 <xsl:if>
 </xsl:for-each>
</Data>

输入:

<Record>
 <Address>
  <Objtyp>H</Objtyp>
  <Objkey>111</Objkey>
  <description>Santa Barbara</description>
 </Address>
 <Address>
   <Objtyp>H</Objtyp>
  <Objkey>112</Objkey>
  <description>San Diego</description>
 </Address>
 <Address>
  <Objtyp>D</Objtyp>
   <parentID>112</parentID>
   <houseNumber>11A</houseNumber>
   <Street>Avenida Del Mundo</Street>
   <Postcode>92118</Postcode>
  <City>Coronado</City>
 </Address>
</Record>

我想要的输出如下:

<Data>  
 <Location>
  <Region>Santa Barbara<Region>
 </Location>
 <Location>
  <Region>San Diego<Region>
  <houseNumber>11A</houseNumber>
  <Street>Avenida Del Mundo</Street>
  <Postcode>92118</Postcode>
  <City>Coronado</City>
 </Location>
</Data>

1 个答案:

答案 0 :(得分:0)

首先,从基于模板的方法开始可能会更好。然后你会有一个模板匹配地址记录与 Objtype ='H'

<xsl:template match="Address[Objtyp='H']">
   <Location>
      ....

您还需要一个模板来匹配其他地址记录,以忽略它们。这样的模板的优先级低于上面更具体的模板

<xsl:template match="Address" />

在从其他节点检索数据方面,密钥通常是更好的方法,因此在您的情况下,您将定义一个密钥,以便通过 parentID 地址记录>价值。

<xsl:key name="child" match="Address" use="parentID" />

然后您可以检索其他值,如下所示:

<xsl:apply-templates select="key('child', Objkey)/houseNumber" />

这样做的好处是,如果相关记录中不存在 houseNumber ,则不会输出任何内容(而不是输出空 houseNumber 元素)。 / p>

最后,要将根记录节点重命名为数据,您也可以使用此模板

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

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:key name="child" match="Address" use="parentID" />

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

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

  <xsl:template match="Address[Objtyp='H']">
    <Location>
      <Region><xsl:value-of select="description"/></Region>
      <xsl:apply-templates select="key('child', Objkey)/houseNumber" />
      <xsl:apply-templates select="key('child', Objkey)/Street" />
      <xsl:apply-templates select="key('child', Objkey)/Postcode" />
      <xsl:apply-templates select="key('child', Objkey)/City" />
    </Location>
  </xsl:template>

  <xsl:template match="Address" />
</xsl:stylesheet>

请注意使用Identity Transform复制现有节点。