在XSLT中选择重复出现的XML节点

时间:2015-09-18 09:33:25

标签: xml xslt xpath

我有以下XML数据:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://kolowrat.at/Letter">
  <letter>
    <sender>
      <title>Mag</title>
      <salutation>Herr</salutation>
      <firstname>Alexander</firstname>
      <lastname>Müller</lastname>
      <street1>Seitenstettengasse 6</street1>
      <zip>3430</zip>
      <city>Linz</city>
      <country>Österreich</country>
    </sender>
    <recipient>
      <title />
      <salutation>Frau</salutation>
      <firstname>Claudia</firstname>
      <lastname>Maier</lastname>
      <street1>Hauptstraße 1</street1>
      <zip>3430</zip>
      <city>Tulln</city>
      <country>Österreich</country>
    </recipient>
    <subject>Ihre Bestellung Nr. 251685489</subject>
    <message>
      <paragraph xsi:type="xsd:string">Ihre Bestellung ist bei uns eingegangen und wird von einem Mitarbeiter vorbereitet und anschließend versandt.</paragraph>
    </message>
  </letter>
  <letter>
    <sender>
      <title>Mag</title>
      <salutation>Herr</salutation>
      <firstname>Michael</firstname>
      <lastname>Haas</lastname>
      <street1>Wienerstraße 1</street1>
      <zip>3430</zip>
      <city>St. Pölten</city>
      <country>Österreich</country>
    </sender>
    <recipient>
      <title />
      <salutation>Herr</salutation>
      <firstname>Claudia</firstname>
      <lastname>Etlinger</lastname>
      <street1>Hauptstraße 1</street1>
      <zip>3430</zip>
      <city>St. Pölten</city>
      <country>Österreich</country>
    </recipient>
    <subject>Ihre Bestellung Nr. 251685489</subject>
    <message>
      <paragraph xsi:type="xsd:string">Ihre Bestellung ist bei uns eingegangen und wird von einem Mitarbeiter vorbereitet und anschließend versandt.</paragraph>
    </message>
  </letter>
</document>

我想用XSL-FO生成一个文档,其中每个字母标签都有自己的页面。这是我的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl fo"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:l="http://kolowrat.at/Letter"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

      <!-- Set the master / page layout -->
      <fo:layout-master-set>
        <fo:simple-page-master master-name="letter" page-height="29.7cm" page-width="21cm" margin-left="2.5cm" margin-right="2.5cm">
          <fo:region-body margin-top="1.5cm" />
        </fo:simple-page-master>
      </fo:layout-master-set>


      <xsl:for-each select="//letter">
        <fo:page-sequence master-reference="letter">
          <fo:flow flow-name="xsl-region-body">
            <xsl:apply-templates select="sender" />
            <xsl:apply-templates select="recipient"/>
            <xsl:apply-templates select="subject" />
            <xsl:apply-templates select="message" />
          </fo:flow>
        </fo:page-sequence>
      </xsl:for-each>
    </fo:root>

  </xsl:template>

  <!-- sender -->
  <xsl:template match="sender">
    <fo:block text-align="right" margin-left="0cm" padding-left="7cm" border-bottom-style="solid">
      <fo:block>
        <xsl:value-of select="salutation"/>&#x00A0;<xsl:value-of select="title"/>&#x00A0;<xsl:value-of select="firstname"/>&#x00A0;<xsl:value-of select="lastname"/>
      </fo:block>
      <fo:block>
        <xsl:value-of select="street1"/>
      </fo:block>
      <fo:block>
        <xsl:if test="street2 != ''">
          <xsl:value-of select="street2"/>
          <fo:block />
        </xsl:if>
      </fo:block>
      <fo:block>
        <xsl:value-of select="zip"/>&#x00A0;<xsl:value-of select="city"/>
      </fo:block>
      <fo:block>
        <xsl:if test="country != ''">
          <xsl:value-of select="country"/>
          <fo:block />
        </xsl:if>
      </fo:block>
    </fo:block>
  </xsl:template>


  <!-- recipient -->
  <xsl:template match="recipient">
    <fo:block padding-top="1.5cm" padding-bottom="2cm">
      <fo:block>
        <xsl:value-of select="salutation"/>&#x00A0;<xsl:value-of select="title"/>&#x00A0;<xsl:value-of select="firstname"/>&#x00A0;<xsl:value-of select="lastname"/>
      </fo:block>
      <fo:block>
        <xsl:value-of select="street1"/>
      </fo:block>
      <fo:block>
        <xsl:if test="street2 != ''">
          <xsl:value-of select="street2"/>
          <fo:block />
        </xsl:if>
      </fo:block>
      <fo:block>
        <xsl:value-of select="zip"/>&#x00A0;<xsl:value-of select="city"/>
      </fo:block>
      <fo:block>
        <xsl:if test="country != ''">
          <xsl:value-of select="country"/>
          <fo:block />
        </xsl:if>
      </fo:block>
    </fo:block>
  </xsl:template>

  <xsl:template match="subject">
    <fo:block padding-bottom="1.5cm" font-weight="bold">
      <xsl:value-of select="current()"/>
    </fo:block>
  </xsl:template>

  <xsl:template match="message">
    <xsl:for-each select="paragraph">
      <fo:block padding-bottom="0.5cm">
        <xsl:value-of select="current()"/>
      </fo:block>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

当我使用FO.NET驱动程序渲染时,我得到了一个emtpy pdf。所以我想我的XPath语句找不到标签。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

这是由于&#34; document&#34;的默认命名空间而发生的。 element - xmlns =&#34; http://kolowrat.at/Letter"

我建议做以下操作(为xpath中文档元素的所有后代指定&#39;字母&#39;名称空间):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl fo"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:l="http://kolowrat.at/Letter"
    xmlns:letter="http://kolowrat.at/Letter"
>

....

      <xsl:for-each select="//letter:letter">
        <fo:page-sequence master-reference="letter">
          <fo:flow flow-name="xsl-region-body">
            <xsl:apply-templates select="letter:sender" />
            <xsl:apply-templates select="letter:recipient"/>
            <xsl:apply-templates select="letter:subject" />
            <xsl:apply-templates select="letter:message" />
          </fo:flow>
        </fo:page-sequence>
      </xsl:for-each>
   ...

  <!-- sender -->
  <xsl:template match="letter:sender">
  ....
</xsl:stylesheet>

请在此处查看更详细的说明:XSLT with XML source that has a default namespace set to xmlns