0


  • <p>标签中的任何<body>标签都应转换为Body_Text.

  • <p>具有最后一个祖先<sec> 但没有属性“ ”的标签sec-type应转换为Flush_Text(此处覆盖第一个Body_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

感谢@Tomalak 在使用ancestorxpath 轴时为我指明了正确的方向。 在这里,我匹配了任何没有属性

的最后一个祖先(我错误地称之为“最高父级”),并将其转换为. 这阻止了本示例中的第一个实例,该实例具有其最后一个祖先,并允许覆盖。 另外,我喜欢 Tomalak 对 H1 - H3 自动化的使用......我仍在尝试这个,并且在我完全理解它之前不想使用它;)<sec><p>sec-typeFlush_Text<p><sec sec-type...Flush_TextBody_Text

于 2012-08-10T02:27:28.910 回答