2

The feedback from my previous post worked a charm but I have encountered the following with some of the documents on our system. The output is as below.

<par def='1'>
   <run>This is start of line one para one </run>
   <run>text hotspot 1</run>
   <run> remainder of line one<break/></run>

   <run>This is line 2 </run>
   <run>another hotspot </run>
   <run>remainder of line 2 <break/></run>
 </par>

Is it possible to generate the following output using XSLT?

<document>
   <para>This is start of line one para one text hotspot 1 remainder of line one</para>

   <para>This is line 2 another hotspot remainder of line 2</para>
</document>

ie, the <break/> node indicates the end of a sentence but a sentence may run over several <run> nodes.

In case anyone is wondering, the source data is generated from Lotus Notes in it's DXL schema format.

I have been using a 3rd party tool to generate my XSLT to date, I'm happy to provide the code but it's not very clean.

Thank you again in advance, becoming a huge fan of this forum.

Dono

4

3 回答 3

1

那这个呢?它只会为 a 中的第一个元素创建新<para>元素,并且如果前一个元素中有 a在其中。<run><par><par><break>

<xsl:template match="par">
  <xsl:for-each select="run[preceding-sibling::run[1]/break or not(preceding-sibling::run)]">
    <para>
      <xsl:apply-templates select="."/>
    </para>
  </xsl:for-each>
</xsl:template>

<xsl:template match="run">
  <xsl:value-of select="."/>
  <xsl:if test="not(break)">
    <xsl:apply-templates select="following-sibling::run[1]"/>
  </xsl:if>
</xsl:template>
于 2012-12-06T11:09:59.360 回答
1

虽然不是一种可取的方法,但它可以按照您的方式工作..

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

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

  <xsl:template match="par">
    <document>
      <para>
        <xsl:apply-templates select="node()"/>
      </para>
    </document>
  </xsl:template>

  <xsl:template match="run">
    <xsl:value-of select="."/>
    <xsl:apply-templates select="break"/>
  </xsl:template>

  <xsl:template match="break">
    <xsl:value-of select="'&#60;/para&#62;'" disable-output-escaping="yes"/>
    <xsl:value-of select="'&#60;para&#62;'" disable-output-escaping="yes"/>
  </xsl:template>
</xsl:stylesheet>
于 2012-12-06T11:47:46.863 回答
0

这种转变

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kPreceding" match="run"
      use="generate-id((following::break|descendant::break)[1])"/>

 <xsl:template match="par">
     <document>
      <xsl:apply-templates select="run/break"/>
     </document>
 </xsl:template>

 <xsl:template match="break">
  <para><xsl:apply-templates select="key('kPreceding', generate-id())/text()"/></para>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<par def='1'>
    <run>This is start of line one para one </run>
    <run>text hotspot 1</run>
    <run> remainder of line one<break/></run>

    <run>This is line 2 </run>
    <run>another hotspot </run>
    <run>remainder of line 2<break/></run>
</par>

产生想要的正确结果:

<document>
   <para>This is start of line one para one text hotspot 1 remainder of line one</para>
   <para>This is line 2 another hotspot remainder of line 2</para>
</document>

说明

这是一个典型的 XSLT 1.0 位置分组解决方案。我们使用一个键来表达一个元素与其标识为一个组break的所有元素之间的关系。run

于 2012-12-06T13:33:48.250 回答