当源包含平面标记时,转换为一个列表中的嵌套项



我有以下XML文件:

<li id="s9781452281988.n39.i34"><i>See also</i>
<a class="term-ref" id="s9781452281988.n39.i6525" href="#s9781452281988.n39.i1899">Emotion</a>;
    <a class="term-ref" id="s9781452281988.n39.i6526" href="#s9781452281988.n39.i3312">Interpersonal conflict</a></li>

我希望输出如下:

<item>See also
 <list rend="runon">
     <item><term>Emotion</term></item>
     <item><term>Interpersonal conflict</term></item>
 </list>
</item>

基本上,如果我有多个a[@class='term-ref'],第一个实例应该启动列表rend="runon"和随后的一个[@class='term-ref']应该包含在item/term列表中。

下面是我的尝试,但它没有像我希望的那样工作,并且在第二个项目/术语(也没有输出的元素)之前关闭列表:

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">
<xsl:template match="li">
    <xsl:element name="item">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>
<xsl:template match="a[@class='term-ref'][1]">
    <xsl:element name="list">
        <xsl:attribute name="rend" select="'runon'"/>
        <xsl:element name="item">
            <xsl:element name="term">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:element>
        <xsl:if test="a[@class='term-ref'][position() >1]">
            <xsl:element name="item">
                <xsl:element name="term">
                    <xsl:apply-templates/>
                </xsl:element>
            </xsl:element>
        </xsl:if>
    </xsl:element>
</xsl:template>
<xsl:template match="li//text()">
    <xsl:value-of select="translate(., '.,;', '')"/>
</xsl:template>
</xsl:stylesheet>

在源XML上,上面的样式表产生如下输出:

<item>See also
<list rend="runon">
    <item><term>Emotion</term></item>
</list>
    Interpersonal conflict</item>

这是不正确的

我做错了什么?

这个简短的转换(几乎完全是"push style",没有条件指令,没有xsl:element,没有translate()replace()那样不必要的函数调用):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:template match="li">
  <item><xsl:apply-templates/></item>
 </xsl:template>
 <xsl:template match="a[@class='term-ref'][1]">
     <list rend="runon">
         <xsl:apply-templates mode="group"
              select="../a[@class='term-ref']"/>
     </list>
 </xsl:template>
 <xsl:template match="a[@class='term-ref']" mode="group">
    <item><term><xsl:apply-templates/></term></item>
 </xsl:template>
 <xsl:template match="a[@class='term-ref']|li/text()" priority="-1"/>
</xsl:stylesheet>

当应用于所提供的XML文档时——其中格式良好:

<li id="s9781452281988.n39.i34"><i>See also</i>
  <a class="term-ref" id="s9781452281988.n39.i6525"
     href="#s9781452281988.n39.i1899">Emotion</a>;
  <a class="term-ref" id="s9781452281988.n39.i6526"
     href="#s9781452281988.n39.i3312">Interpersonal conflict.</a>.
</li>

生成所需的正确结果:

<item>See also<list rend="runon">
      <item>
         <term>Emotion</term>
      </item>
      <item>
         <term>Interpersonal conflict.</term>
      </item>
   </list>
</item>

应该可以…

XML输入(格式良好)

<doc>
    <li id="s9781452281988.n39.i34"><i>See also</i>
        <a class="term-ref" id="s9781452281988.n39.i6525" href="#s9781452281988.n39.i1899">Emotion</a>;
        <a class="term-ref" id="s9781452281988.n39.i6526" href="#s9781452281988.n39.i3312">Interpersonal conflict.</a>.
    </li>
</doc>
XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="li">
        <item>
            <xsl:apply-templates select="i/text()"/>
            <xsl:if test="a">
                <list rend="runon">
                    <xsl:apply-templates select="a"/>                   
                </list>
            </xsl:if>
        </item>
    </xsl:template>
    <xsl:template match="a">
        <item><term><xsl:apply-templates select="node()"/></term></item>
    </xsl:template>
    <xsl:template match="li//text()">
        <xsl:value-of select="replace(.,'[.,;]','')"/>
    </xsl:template>
</xsl:stylesheet>

<doc>
   <item>See also<list rend="runon">
         <item>
            <term>Emotion</term>
         </item>
         <item>
            <term>Interpersonal conflict</term>
         </item>
      </list>
   </item>
</doc>

这应该是你想要做的:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs"
version="2.0">
  <xsl:template match="li">
    <xsl:element name="item">
      <xsl:apply-templates select="node()" />
      <xsl:apply-templates select="." mode="items" />
    </xsl:element>
  </xsl:template>
  <xsl:template match="li//text()">
    <xsl:value-of select="normalize-space(translate(., '.,;', ''))"/>
  </xsl:template>
  <xsl:template match="a[@class = 'term-ref']" />
  <xsl:template match="node()" mode="items" />
  <xsl:template match="li" mode="items">
    <xsl:apply-templates mode="items" />
  </xsl:template>
  <xsl:template match="li[count(a[@class = 'term-ref']) > 1]" mode="items">
    <list rend="runon">
      <xsl:apply-templates select="a[@class = 'term-ref']" mode="items" />
    </list>
  </xsl:template>
  <xsl:template match="a[@class = 'term-ref']" mode="items">
    <item>
      <term>
        <xsl:value-of select="."/>
      </term>
    </item>
  </xsl:template>
</xsl:stylesheet>

当在示例输入上运行时,将产生:

<item>
  See also<list rend="runon">
    <item>
      <term>Emotion</term>
    </item>
    <item>
      <term>Interpersonal conflict</term>
    </item>
  </list>
</item>

当在只有一个a.term-ref的输入文件上运行时,将产生:

<item>
  See also<item>
    <term>Interpersonal conflict</term>
  </item>
</item>

最新更新