如何使用模板遍历嵌套的XML结构

Dom*_*Dom 3 xml xslt nested

我是XSL的新手,并且正在从头开始解决问题。

我有一个包含以下结构的源XML文件:

<root>
  <Header>

  </Header>

  <DetailRecord>
    <CustomerNumber>1</CustomerNumber>
    <DetailSubRecord>
      <Address>London</Address>
    </DetailSubRecord>
    <DetailSubRecord>
      <Address>Hull</Address>
    </DetailSubRecord>

  </DetailRecord>

  <DetailRecord>
    <CustomerNumber>2</CustomerNumber>
    <DetailSubRecord>
      <Address>Birmingham</Address>
    </DetailSubRecord>
    <DetailSubRecord>
      <Address>Manchester</Address>
    </DetailSubRecord>

  </DetailRecord>
  <Footer>

  </Footer>

</root>
Run Code Online (Sandbox Code Playgroud)

其中有<DetailRecord>多个<DetailSubRecord>s ,其中有多个s。

我已经设法将一个XSL放到一个平面文件中,该XSL将一个嵌套的多个DetailRecords集输出到一个平面文件中,但是我一直不知道如何在XSL中引用地址记录的第二个嵌套级别。

到目前为止,这是我的XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output method="text"/>
  <xsl:variable name="spaces" select="' '"/>
  <xsl:variable name="newline">
    <xsl:text>&#10;</xsl:text>
  </xsl:variable>
  <xsl:template match="/">
    <xsl:value-of select="root/Header/HeaderField"/>
    <xsl:copy-of select="$newline"/>
    <xsl:for-each select="root/DetailRecord">
      <xsl:value-of select="CustomerNumber"/>
      <xsl:copy-of select="$newline"/>
    </xsl:for-each>
    Trailer - recordCount - <xsl:value-of select="count(root/DetailRecord)"/>
  </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

Fly*_*179 5

XSLT是一种功能语言,而不是过程语言;XSLT的大多数新手并没有意识到,XSLT处理器会按照它们在源代码中出现的顺序自动处理树中的每个节点。但是,如果没有模板来定义如何处理每个节点,则不会输出任何内容。

在大多数情况下,您不需要<xsl:for-each>仅仅处理子元素,这已经为您完成,您只需要定义一个模板来描述希望每个元素如何输出。像这样:

<xsl:template match="root">
  <xsl:apply-templates />
  <xsl:text>Trailer - recordCount - </xsl:text>
  <xsl:value-of select="count(DetailRecord)" />
</xsl:template>

<xsl:template match="HeaderField | CustomerNumber | Address">
  <xsl:value-of select="concat(.,$newline)" />
</xsl:template>

<xsl:template match="DetailSubRecord">
  <!-- do something with subrecord here -->
  <xsl:apply-templates />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

<xsl:apply-templates />一个模板中的只是告诉XSLT处理器处理子元素,然后再添加记录计数。

第二个模板处理其match属性中具有三个名称的任何元素,并在每种情况下输出.与新行连接的content()。

当前形式的第三个模板实际上是多余的,处理器仍然可以执行此操作,但是您可以使用更有用的内容替换该注释。

您会注意到,这并没有提供有关如何处理DetailRecord元素的任何信息。因为您要做的只是处理它的孩子,所以您无需指定任何内容,因为这是给定的。