<p>
标记中的任何 <body>
标记都应转换为Body_Text
。
具有最后一个祖先<p>
而不属性“<sec>
”的sec-type
代码应转换为Flush_Text
(这会覆盖第一个Body_Text
转换。)
具有最后一个祖先<p>
( 属性“<sec sec-type="irrelevant-attribute-name>
”)的sec-type
代码应转换为{{1} }。
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>
...这是我的XSL, 不 正常工作:
<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: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
。
答案 0 :(得分: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>
答案 1 :(得分: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指导我使用ancestor
xpath轴的正确方向。
在这里,我匹配了 不 的任何<sec>
中的最后一个祖先(我错误地称之为“最高父级”)<p>
属性sec-type
,并将其转换为Flush_Text
。这阻止了此示例中<p>
的第一个实例,其<sec sec-type...
作为其“最后一个祖先”,而不是Flush_Text
并允许Body_Text
覆盖。
另外,我喜欢Tomalak使用H1-H3的自动化...我还在试验这个,并且在我完全理解它之前不想使用它;)