3

XML コンテンツに一連の P タグがあり、それらの開始値内にセマンティック階層がありますが、P タグは線形です。XSLT 2 変換を探しています。

セマンティック階層は次のとおりです。

(1)
 +-(a)
    +-(I)
       +-(A)

次のように RegEx シーケンスを使用します。

<xsl:param name="patternOrder" as="element(pattern)*" xmlns="">
  <pattern level="1" value="^(\([0-9]+(\.[0-9]+)?\))" />
  <pattern level="2" value="^(\([a-z]\))" />
  <pattern level="3" value="^(\((IX|IV|V?I{{0,3}})\))" />
  <pattern level="4" value="^(\([\w]+(\.[\w]+)?\))" />
</xsl>

データセットを確認した後、さまざまな条件があります。

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <content>
        <p>(1) blah</p>
        <p>(2)(a) blah</p>
        <p>(b) blah</p>
        <p>(3)(a)(I) blah</p>
        <p>(II) blah</p>
        <p>(A) blah</p>
        <p>(B.1) blah</p>
        <p>(b) blah</p>
        <p>(4) blah</p>
        <p>(4.5) blah</p>
        <p>(5)(a)(I)(A) blah</p>
        <p>(B) blah</p>
        <p>(II) blah</p>
        <p>(III)(a) blah</p>
        <p>(bb.2) blah</p>
        <p>(6) blah</p>
    </content>
    <content>
        <p>blah</p>
    </content>
    <content>
        <p>blah</p>
        <p>(1) blah</p>
        <p>(a) blah</p>
        <p>(b) blah</p>
        <p>(2) blah </p>
    </content>
</test>

...最終結果は次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <content>
        <p>(1) blah</p>
        <p>(2)
            <p>(a) blah</p>
            <p>(b) blah</p>
        </p>
        <p>(3)
            <p>(a)
                <p>(I) blah</p>
                <p>(II) blah
                    <p>(A) blah</p>
                    <p>(B) blah</p>
                </p>
            </p>
            <p>(b) blah</p>
        </p>
        <p>(4) blah</p>
        <p>(4.5) blah</p>
        <p>(5)
            <p>(a)
                <p>(I)
                    <p>(A) blah</p>
                    <p>(B.1) blah</p>
                </p>      
                <p>(II) blah</p>
                <p>(III)</p>
                    <p>(a) blah</p>
                    <p>(bb.2) blah</p>
                </p>
            </p>
        <p>(6) blah</p>
    </content>
    <content>
        blah
    </content>
    <content>
        blah
        <p>(1) blah
            <p>(a) blah</p>
            <p>(b) blah</p>      
        </p>
        <p>(2) blah </p>
    </content>
</test>

セマンティック階層が P タグに存在しない場合の条件に注意してください。その場合、P タグは削除され、その親コン​​テンツ要素の値になります。

編集:

次の正規表現を使用して、すべてのセマンティック条件を検出できました。

^(\(([\w]+(\.[\w]+)?)\)){1,4}

*編集#2 *

レベリング属性の場合:

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <content>
        <p level="1">(1) blah</p>
        <p level="1">(2)</p>
        <p level="2">(a) blah</p>
        <p level="2">(b) blah</p>
        <p level="1">(3)</p>
        <p level="2">(a)</p>
        <p level="3">(I) blah</p>
        <p level="3">(II) blah</p>
        <p level="4">(A) blah</p>
        <p level="4">(B.1) blah</p>
        <p level="2">(b) blah</p>
        <p level="1">(4) blah</p>
        <p level="1">(4.5) blah</p>
        <p level="1">(5)</p>
        <p level="2">(a)</p>
        <p level="3">(I)</p>
        <p level="4">(A) blah</p>
        <p level="4">(B) blah</p>
        <p level="3">(II) blah</p>
        <p level="3">(III)</p>
        <p level="2">(a) blah</p>
        <p level="2">(bb.2) blah</p>
        <p level="2">(6) blah</p>
    </content>
    <content>
        <p>blah</p>
    </content>
    <content>
        <p>blah</p>
        <p level="1">(1) blah</p>
        <p level="2">(a) blah</p>
        <p level="2">(b) blah</p>
        <p level="1">(2) blah </p>
    </content>
</test>
4

1 に答える 1

2

第 1 段階: 変換

<p>(2)(a) blah</p>
<p>(b) blah</p>

の中へ

<p>(2)</p>
<p>(a) blah</p>
<p>(b) blah</p>

のようなものを使用して

<xsl:template match="p">
  <xsl:for-each select="tokenize(., '\(')">
     <xsl:if test="normalize-space(.)">
       <p>(<xsl:value-of select="."/></p>
     </xsl:if>
  </xsl:for-each>
</xsl:template>

第二段階:

まず関数を書く

<xsl:function name="f:level" as="xs:integer">
  <xsl:param name="p" as="element(p)"/>
  ....
</xsl:function>

これは、正規表現の一致に基づいて「セマンティック レベル」を計算します。あなたはこの部分のやり方を知っているようです。

次に、再帰的なグループ化関数を書きます:

<xsl:function name="f:group" as="element(p )*">
  <xsl:param name="in" as="element(p )*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:for-each-group select="$in" group-starting-with="p[f:level(.)=$level]">
    <p><xsl:value-of select="current-group()[1]"/>
      <xsl:sequence select="f:group(current-group()[position() gt 1], $level+1)"/>
    </p>
  </xsl:for-each-group>
</xsl:function>

この関数を次のように呼び出します。

<xsl:template match="content">
  <xsl:sequence select="f:group(p, 1)"/>
</xsl:template>

未検証。

于 2013-11-10T08:57:19.647 に答える