我的某些文件存在问题,可以使用帮助解决它。我正在从html转换为xml。有时我自己有<b>
或<u>
或<i>
标记,我使用
<xsl:template match="i">
<emphasis italic="yes">
<xsl:apply-templates select="*|@*|text()"/>
</emphasis>
</xsl:template>
或粗体表示b和下划线表示你。
有时我在<u>
<b>
对于这些我使用
<xsl:template match="b/u">
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
这是为了摆脱u
<xsl:template match="b[u]">
<emphasis bold="yes" underline="yes">
<xsl:apply-templates select="*|@*|text()"/>
</emphasis>
</xsl:template>
这是为了转换b
后跟u
。
现在我的问题是当u
嵌套在i
嵌套在b
时,该怎么做。这是什么代码?
答案 0 :(得分:0)
要回答您的直接问题,要匹配嵌套在u
i
中b
的{{1}},您可以这样做
<xsl:template match="b/i/u">
您还需要模板来处理父b
和i
<xsl:template match="b[i/u]">
<xsl:template match=b/i[u]">
但是大概你想要处理以任何顺序嵌套的元素?每个可能的permuation的编码模板将变得非常混乱,您还必须担心匹配相同元素的两个模板。
相反,试试这个稍微灵活的XSLT,虽然不是特别优雅
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="i[parent::b|parent::u]" name="italic">
<xsl:attribute name="italic">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="b[parent::i|parent::u]" name="bold">
<xsl:attribute name="bold">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="u[parent::b|parent::i]" name="underline">
<xsl:attribute name="underline">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="*[self::b|self::i|self::u][not(parent::b)][not(parent::i)][not(parent::u)]">
<emphasis>
<xsl:choose>
<xsl:when test="self::b">
<xsl:call-template name="bold"/>
</xsl:when>
<xsl:when test="self::i">
<xsl:call-template name="italic"/>
</xsl:when>
<xsl:when test="self::u">
<xsl:call-template name="underline"/>
</xsl:when>
</xsl:choose>
</emphasis>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我们的想法是,您拥有与i
,b
或u
元素匹配的模板,这些元素具有其他元素作为父元素。在这种情况下,您只需输出相关属性。
您还拥有与最高i
,b
或u
元素匹配的主模板(即没有其他元素作为父元素的元素),您输出重点元素。请注意,使用命名模板更简单,以避免某些代码重复。
将其应用于以下XML
时<test>
<b>bold</b>
<i>Italic</i>
<b><i>bold Italic</i></b>
<u><b><i>bold Italic underline</i></b></u>
</test>
以下是输出
<test>
<emphasis bold="yes">bold</emphasis>
<emphasis italic="yes">Italic</emphasis>
<emphasis bold="yes" italic="yes">bold Italic</emphasis>
<emphasis underline="yes" bold="yes" italic="yes">bold Italic underline</emphasis>
</test>
答案 1 :(得分:0)
这是一个简单而简短的解决方案:只有两个模板,没有明确的条件指令:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:names>
<n short="b">bold</n>
<n short="i">italic</n>
<n short="u">underline</n>
</my:names>
<xsl:variable name="vNames" select="document('')/*/my:names/*"/>
<xsl:template match=
"node()[not(contains('+b+i+u+', concat('+',name(),'+')))]
/*[contains('+b+i+u+', concat('+',name(),'+'))]
">
<emphasis>
<xsl:apply-templates select="." mode="emph"/>
</emphasis>
</xsl:template>
<xsl:template mode="emph"
match="*[contains('+b+i+u+', concat('+',name(),'+'))]">
<xsl:attribute name="{$vNames[@short=name(current())]}">yes</xsl:attribute>
<xsl:apply-templates select="node()" mode="emph"/>
</xsl:template>
</xsl:stylesheet>
对以下XML文档应用此转换时:
<test>
<b>bold</b>
<i>Italic</i>
<b><i>bold Italic</i></b>
<u><b><i>bold Italic underline</i></b></u>
</test>
产生了想要的正确结果:
<emphasis bold="yes">bold</emphasis>
<emphasis italic="yes">Italic</emphasis>
<emphasis bold="yes" italic="yes">bold Italic</emphasis>
<emphasis underline="yes" bold="yes" italic="yes">bold Italic underline</emphasis>