0


  • <p>タグ内のタグはすべて<body>に変換する必要がありますBody_Text

  • 属性""のない最後<p>の祖先を持つタグは、に変換する必要があります(これはここでの最初の変換をオーバーライドします)。<sec> sec-typeFlush_TextBody_Text

  • <p>最後の祖先(属性 "")を持つタグは<sec sec-type="irrelevant-attribute-name>に変換するsec-type必要がありますBody_Text




<sec><p>asdf</p></sec>に変換する必要があります<sec><Flush_Text>asdf</Flush_Text></sec>

<sec sec-type="whatevs"><p>asdf</p></sec>である必要があります<sec sec-type="whatevs"><Body_Text>asdf</Body_Text></sec>


またsec-type、この属性を使用して祖先にさらにネストする場合は、Body_Text

<sec sec-type="whatevs"><sec><p>asdf</p></sec></sec>である必要があります<sec sec-type="whatevs"><sec><Body_Text>asdf</Body_Text></sec>




これが私のXMLです:

<root>
  <body>
  <sec sec-type="asdf">
    <title>This is an H1</title>

    <sec>
      <title>This is an H2</title>

      <sec>
        <title>This is an H3</title>
        <p>This SHOULD be "Body_Text", but it's "Flush_Text"</p>
      </sec> <!-- end of H3 -->
    </sec> <!-- end of H2 -->
  </sec> <!-- end of H1 -->

  <sec>
    <p>This is Flush_Text</p>
  </sec>
    <p>This is Body_Text</p>
  </body>
</root>


...これが私のXSLですが、正しく機能して いません:

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

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

        <!-- Body_Text -->
        <xsl:template match="body//p">
            <Body_Text>
                <xsl:apply-templates select="@*|node()"/>
            </Body_Text>
        </xsl:template>

        <!-- Flush_Text -->
        <xsl:template match="sec//p">
          <xsl:if test="not(@sec-type)">
            <Flush_Text>
                <xsl:apply-templates select="@*|node()"/>
            </Flush_Text>
          </xsl:if>
        </xsl:template>

        <!-- H1 -->
        <xsl:template match="sec//title">
            <H1>
                <xsl:apply-templates select="@*|node()"/>
            </H1>
        </xsl:template>

        <!-- H2 -->
        <xsl:template match="sec//sec//title">
            <H2>
                <xsl:apply-templates select="@*|node()"/>
            </H2>
        </xsl:template>

        <!-- H3 -->
        <xsl:template match="sec//sec//sec//title">
            <H3>
                <xsl:apply-templates select="@*|node()"/>
            </H3>
        </xsl:template>
</xsl:stylesheet>


...そしてここに間違った出力があります:

<?xml version="1.0" encoding="utf-16"?>
<root>
    <body>
        <sec sec-type="asdf">
            <H1>This is an H1</H1>
            <sec>
                <H2>This is an H2</H2>
                <sec>
                    <H3>This is an H3</H3>
                    <Flush_Text>This SHOULD be "Body_Text", but it's "Flush_Text"</Flush_Text>
                </sec>
                <!-- end of H3 -->
            </sec>
            <!-- end of H2 -->
        </sec>
        <!-- end of H1 -->
        <sec>
            <Flush_Text>This is Flush_Text</Flush_Text>
        </sec>
        <Body_Text>This is Body_Text</Body_Text>
    </body>
</root>

<p>この例の最初のインスタンスはに変換する必要がありますBody_Textが、として変換されていることに注意してくださいFlush_Text

4

2 に答える 2

1

これが私があなたが望むと思うことをする解決策です。あなたの質問を解釈するのは難しいです。

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

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

  <xsl:template match="title">
    <xsl:element name="H{count(ancestor::sec) + 1}">
      <xsl:apply-templates select="node() | @*" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="p[ancestor::sec[last()][@sec-type]]">
    <Body_Text>
      <xsl:apply-templates select="node() | @*" />
    </Body_Text>
  </xsl:template>

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

</xsl:stylesheet>

http://www.xmlplayground.com/vmuroB

于 2012-08-09T22:12:33.153 に答える
0

ここで必要な結果を生成するために、ステートメント<xsl:template match="sec//p">(Flush_Text の下の XSL 内) を に変更し<xsl:template match="p[ancestor::sec[last()][not(@sec-type)]]">、if ステートメントも削除しました。

修正された XSL は次のとおりです。

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

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

        <!-- Body_Text -->
        <xsl:template match="body//p">
            <Body_Text>
                <xsl:apply-templates select="@*|node()"/>
            </Body_Text>
        </xsl:template>

    <!-- Flush_Text -->
    <xsl:template match="p[ancestor::sec[last()][not(@sec-type)]]">
        <Flush_Text>
            <xsl:apply-templates select="@*|node()"/>
        </Flush_Text>
    </xsl:template>

        <!-- H1 -->
        <xsl:template match="sec//title">
            <H1>
                <xsl:apply-templates select="@*|node()"/>
            </H1>
        </xsl:template>

        <!-- H2 -->
        <xsl:template match="sec//sec//title">
            <H2>
                <xsl:apply-templates select="@*|node()"/>
            </H2>
        </xsl:template>

        <!-- H3 -->
        <xsl:template match="sec//sec//sec//title">
            <H3>
                <xsl:apply-templates select="@*|node()"/>
            </H3>
        </xsl:template>
</xsl:stylesheet>

...この目的の出力を生成します:

<root>
<body>
<sec sec-type="asdf">
<H1>This is an H1</H1>
<sec>
<H2>This is an H2</H2>
<sec>
<H3>This is an H3</H3>
<Body_Text>This SHOULD be "Body_Text", but it's "Flush_Text"</Body_Text>
</sec>

</sec>

</sec>

<sec>
<Flush_Text>This is Flush_Text</Flush_Text>
</sec>
<Body_Text>This is Body_Text</Body_Text>
</body>
</root>


これはhttp://xslt.online-toolz.com/tools/xslt-transformation.php でテストされました 。 xpath軸

の使用において正しい方向を示してくれた@Tomalakに感謝します。 ここでは、最後の祖先 (誤って「最上位の親」と呼んでいたもの) を属性を持たないものから照合し、それを として変換しました。これにより、この例の の最初のインスタンス (最後の祖先として持つ) が存在しなくなり、をオーバーライド できるようになります。 また、Tomalak の H1 - H3 の自動化の使用が気に入っています... 私はまだこれを試していて、完全に理解するまで使いたくありません ;)ancestor

<sec><p>sec-typeFlush_Text<p><sec sec-type...Flush_TextBody_Text

于 2012-08-10T02:27:28.910 に答える