xml XSLT:如果标签存在,应用模板;如果没有,请选择静态值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5791053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 14:40:34  来源:igfitidea点击:

XSLT: If tag exists, apply template; if not, choose static value

xmlxsltxslt-2.0xslt-1.0

提问by Issa Fram

I am new to XSLT in general so please bear with me...

我是 XSLT 的新手,所以请耐心等待...

With that in mind, what I am trying to do is check for a certain tag in the XML. If it is there I want to apply a template. If not, I want to add it (as a blank value). Basically always forcing it to be in the final output. How would I do this?

考虑到这一点,我要做的是检查 XML 中的某个标签。如果在那里,我想应用一个模板。如果没有,我想添加它(作为空白值)。基本上总是强迫它在最终输出中。我该怎么做?

I had something like this...

我有这样的事情...

<xsl:choose>
    <xsl:when test="@href">
        <xsl:apply-templates select="country" />
    </xsl:when>
    <xsl:otherwise>
    </xsl:otherwise>
</xsl:choose>

The top poriton of the code is what I think I have wrong. Need something in the otherwisetag and my whenpart is wrong i think.

代码的最高部分是我认为我错的地方。otherwise标签中需要一些东西,when我认为我的部分是错误的。

<xsl:template match="country">
    <xsl:if test=". != '' or count(./@*) != 0">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:template>

Can anyone help? Thank you in advance.

任何人都可以帮忙吗?先感谢您。

EDIT:

编辑:

Yes in the end i need at the very least a <country />tag to be in the XML. But it is possible that it does not exist at all. If it doesn't exist, I have to put it in. An example good input would be <country>US</country>

是的,最后我至少需要一个<country />标记在 XML 中。但它是可能的,它并不存在于所有。如果它不存在,我必须把它放进去。一个好的输入例子是<country>US</country>

采纳答案by Martin Honnen

In the template for the parent element the country element is expected to be in use e.g.

在父元素的模板中,预计使用 country 元素,例如

<xsl:template match="foo">
  <xsl:if test="not(country)">
    <country>US</country>
  </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

Instead of foouse the name of the parent element. And of course you could also do other stuff like copying the element, I have focused on the ifcheck. You do not really need an xsl:choose/when/otherwisein my view, the xsl:ifshould suffice as the apply-templates will not do anything with child elements that don't exist.

而不是foo使用父元素的名称。当然你也可以做其他的事情,比如复制元素,我专注于if检查。xsl:choose/when/otherwise在我看来,您并不真正需要 an ,xsl:if应该足够了,因为 apply-templates 不会对不存在的子元素执行任何操作。

回答by Dimitre Novatchev

Even simpler:

更简单

<xsl:template match="foo[not(country)]">
        <country>US</country>
    <xsl:apply-templates/>
</xsl:template>

Do note:

请注意

No XSLT conditional instructions(such as <xsl:if>) are usedand they are not necessary.

没有XSLT条件指令(如<xsl:if>使用,他们是没有必要的。

Very often, the presence of <xsl:if>or <xsl:choose>is an indication that the code can be refactored and significantly improved by, among other things, getting rid of the conditional instructions.

很多时候,存在<xsl:if><xsl:choose>表明代码可以重构和显着改进,其中包括摆脱条件指令。

回答by Dimitre Novatchev

You don't even need any kind of Conditional Processing. This stylesheet:

您甚至不需要任何类型的Conditional Processing。这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="item[not(country)]">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
            <country>Lilliput</country>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

With this input:

有了这个输入:

<root>
    <item>
        <country>Brobdingnag</country>
    </item>
    <item>
        <test/>
    </item>
</root>

Output:

输出:

<root>
    <item>
        <country>Brobdingnag</country>
    </item>
    <item>
        <test></test>
        <country>Lilliput</country>
    </item>
</root>