2

次の形式の (不正な形式の DITA) XML があります。

<dl>
<dlentry><dt>BLARG</dt>
<dd>BLARG Definition</dd>
<dt>BLARG2</dt>
<dd>BLARG2 Definition</dd></dlentry>
</dl>
<dl>
<dlentry><dt>BLARG3</dt>
<dd>BLARG3 Definition</dd></dlentry>
</dl>
<p>Continuation of BLARG3 definition.</p>
<note>Note pertaining to BLARG3 definition</note>

等々。

私がやろうとしているのは、この一連の<dl>要素を単一の に統合すること<dl>です。これは次のようになります。

<dl>
    <dlentry><dt>BLARG</dt>
       <dd>BLARG Definition</dd></dlentry>
    <dlentry><dt>BLARG2</dt>
       <dd>BLARG2 Definition</dd></dlentry>
    <dlentry><dt>BLARG3</dt>
       <dd>BLARG3 definition. Continuation of BLARG3 definition.
       <note>Note pertaining to BLARG3 definition</note></dd></dlentry>
<dl>

次のように、キーを使用して、前の の値に従ってノード<p>またはノードにインデックスを付けようとしています。<note>generate-id()<dd>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="kFollowing" match="p|note|table" use="generate-id(preceding::dd[1])"/>
  <!-- identity template -->
<xsl:template match="@*|node()" name="identity">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="dl">
    <xsl:choose>
        <xsl:when test="count(preceding::dl)=0">
            <!--We only want to process the first dl. All others should be ignored, because their content will get included in this one.-->
            <dl>
                <!--Want to grab all following terms, except ones that contain phrase elements, which need to be turned into a table because they are field values-->
                <xsl:for-each select="following::dt[not(child::ph)]|descendant::dt">
                    <dlentry>
<dt><xsl:value-of select="normalize-space(.)"/></dt>
                        <xsl:variable name="ddID"><xsl:value-of select="generate-id(following::dd[1])"/></xsl:variable>
                        <dd><xsl:for-each select="following::dd[1]">
                            <xsl:apply-templates/><xsl:text>. </xsl:text>
                        </xsl:for-each>
                            <xsl:variable name="ddKey" select="key('kFollowing',generate-id(following::dd[1]))"/>
                            <xsl:for-each select="following::*[$ddKey]">
                               <xsl:apply-templates/>
</xsl:for-each>
                        </dd>
                    </dlentry>
                </xsl:for-each>
            </dl>   
        </xsl:when>
        <xsl:otherwise/>
    </xsl:choose>
</xsl:template>
4

2 に答える 2

1
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <!-- using a test root -->
    <xsl:template match="/test">
        <dl>
            <xsl:apply-templates select="dl/*/dt" />
        </dl>
    </xsl:template>

    <!-- assuming that we have always a dd for each dt -->
    <xsl:template match="dt">
        <dlentry>
            <xsl:copy-of select="."/>
            <dd>
             <xsl:value-of select="following::*[1]"/>
             <!-- just check the node after dd or dlentry or dl -->
             <xsl:apply-templates select="following::*[2]
                [local-name()='p' or 
                 local-name()='note' or 
                 local-name()='table']"/>
            </dd>

        </dlentry>
    </xsl:template>

    <xsl:template match="p|note|table">
        <xsl:copy-of select="."/>
        <!-- copy next node only if wanted -->
        <xsl:apply-templates select="following::*[1]
                [local-name()='p' or 
                 local-name()='note' or 
                 local-name()='table']"/>
    </xsl:template>

</xsl:stylesheet>
于 2012-06-13T22:32:36.723 に答える
1

この変換:

<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="kFollowing" match="p|note"
      use="generate-id(preceding-sibling::dl[1]/dlentry)"/>

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

     <xsl:template match="dl[1]">
      <dl>
       <xsl:apply-templates select="../dl/dlentry"/>
      </dl>
     </xsl:template>

     <xsl:template match="dd">
      <dd>
        <xsl:value-of select="."/>
        <xsl:copy-of select="key('kFollowing', generate-id(..))/self::p/text()"/>
        <xsl:copy-of select="key('kFollowing', generate-id(..))/self::note"/>
      </dd>
     </xsl:template>
     <xsl:template match="dl|p|note"/>
</xsl:stylesheet>

次の XML ドキュメント(単一の最上位要素にラップされた提供されたフラグメント) に適用された場合:

<t>
    <dl>
        <dlentry>
            <dt>BLARG</dt>
            <dd>BLARG Definition</dd>
            <dt>BLARG2</dt>
            <dd>BLARG2 Definition</dd>
        </dlentry>
    </dl>
    <dl>
        <dlentry>
            <dt>BLARG3</dt>
            <dd>BLARG3 Definition</dd>
        </dlentry>
    </dl>
    <p>Continuation of BLARG3 definition.</p>
    <note>Note pertaining to BLARG3 definition</note>
</t>

必要な正しい結果が生成されます。

<t>
   <dl>
      <dlentry>
         <dt>BLARG</dt>
         <dd>BLARG Definition</dd>
         <dt>BLARG2</dt>
         <dd>BLARG2 Definition</dd>
      </dlentry>
      <dlentry>
         <dt>BLARG3</dt>
         <dd>BLARG3 DefinitionContinuation of BLARG3 definition.<note>Note pertaining to BLARG3 definition</note>
         </dd>
      </dlentry>
   </dl>
</t>

". "これは要件として述べられておらず、OP による単なる装飾である可能性があるため、意図的に 2 つのテキスト ノード間に区切り文字を生成していません。これを行うには、少し追加の作業が必要であり、読者の演習として残されています:)。

于 2012-06-14T02:18:13.963 に答える