1

次のようなxmlドキュメントがあります。

<div>
  <p>Hello my name is Bob <cb ed="#R" n="1/>and I live in a house</p>
  <p>My name is Susan.</p>
  <p>Where are you from?</p>
  <p>I am from <cb ed="#R" n="2/>Chicago, Illinois</p>
  <p>I also live in Chicago</p>
  <p>But I wish I <cb ed="#R" n="3"/>lived in New York</p>
</div>

等々 ...

私は基本的にそれを変換して、タグが最初と2番目の間のすべてのものを囲むようにしたいと思っています...しかし、新しく作成されたdiv内の既存の段落も保持したいと思います。これは、

要素の直後の兄弟であるテキスト ノードをタグで囲みます。

結果を次のようにしたい:

   <div id="1">
     <p>and I live in a house</p>
     <p>My name is Susan.</p>
     <p>Where are you from?</p>
     <p>I am from</p> 
   </div>
   <div id="2">
     <p>Chicago, Illinois</p>
     <p>I also live in Chicago</p>
     <p>But I wish I</p> 
   </div>
   <div id="3">
     <p>lived in New York</p>
   </div>

これはかなり難しいことがわかっています。誰かが私が正しい軌道に乗るのを手伝ってくれるか、または同様の種類の変換の例を教えてくれるのだろうか.

これが私がこれまでに持っているものです:

    <xsl:template match="tei:p">
        <xsl:choose>
            <xsl:when test="./tei:cb[@ed='#R']">
                <xsl:variable name="number" select="./tei:cb[@ed='#R']/@n"/>
                <div id="{$number}">
                    <span>test</span>
                    <xsl:for-each select="./tei:cb[@ed='#R']/following::p[preceding::tei:cb[@ed='#R']]">
                        <p><xsl:value-of select="."/></p>
                    </xsl:for-each>
                </div>
            </xsl:when>
            <xsl:otherwise>

            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

これまでのところ、唯一の結果は次のとおりです。

     <div id="1rb"><span>test</span></div>
     <div id="1va"><span>test</span></div>
     <div id="1vb"><span>test</span></div>
4

2 に答える 2

1

<cb>常に同じレベル (内)で発生すると仮定すると、<p>これは多かれ少なかれ「フラット xml フォームから階層 xml を作成する」のようなものであるか、おそらくKayessian メソッドに目を向けます。

このようなことを試してください(まだ改善のために開いています):

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*" />
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="p[cb]" >
        <!-- following siblings including next p[cb]  -->
        <xsl:variable name="fs" select="following-sibling::*[ 
                                             generate-id( preceding-sibling::p[cb][1]
                                          ) = generate-id(current()) ]" />

        <div id="{cb/@n}">
            <xsl:apply-templates select="cb" mode="start"/>
            <xsl:apply-templates select="$fs[position() != last()]" />
            <xsl:apply-templates select="$fs[last()]" mode="stop"/>
        </div>
    </xsl:template>

    <xsl:template match="p[cb]" mode="stop">
        <p>
            <xsl:copy-of select="cb/preceding-sibling::node()"/>
        </p>
    </xsl:template>

    <xsl:template match="cb[parent::p]" mode="start">
        <p>
            <xsl:copy-of select="following-sibling::node()"/>
        </p>
    </xsl:template>

    <xsl:template match="div[p/cb]">
        <xsl:copy>
            <xsl:apply-templates select="p[cb][1]" mode="stop"/>
            <xsl:apply-templates select="p[cb]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

次の出力が生成されます。

  <div>
    <p>Hello my name is Bob </p>
    <div id="1">
      <p>and I live in a house</p>
      <p>My name is Susan.</p>
      <p>Where are you from?</p>
      <p>I am from </p>
    </div>
    <div id="2">
      <p>Chicago, Illinois</p>
      <p>I also live in Chicago</p>
      <p>But I wish I </p>
    </div>
    <div id="3">
      <p>lived in New York</p>
    </div>
  </div>
于 2013-06-12T07:37:06.617 に答える
1

以下は私にとってはうまくいきます。カウント手法を使用して、2 つのcb要素間のテキスト ノードを見つけます。

<xsl:template match="div">
    <xsl:apply-templates select=".//cb"/>
</xsl:template>

<xsl:template match="cb">
    <div id="{@n}">
        <xsl:variable name="numTextNodes" select="count(following::text()) - count(following::cb/following::text())"/>
        <xsl:for-each select="following::text()[position() &lt;= $numTextNodes]">
            <xsl:if test="normalize-space()">
                <p>
                    <xsl:value-of select="normalize-space()"/>
                </p>
            </xsl:if>
        </xsl:for-each>
    </div>
</xsl:template>
于 2013-06-11T21:05:12.883 に答える