【问题标题】:Using If in XSL在 XSL 中使用 If
【发布时间】:2012-07-23 18:47:17
【问题描述】:

您好,我正在尝试在 xsl 中使用 if 将输入 xml 转换为其他 xml。 可以实现对某些无法获得准确输出的部分。帮助会很高兴。

输入 Xml:

<?xml version="1.0" encoding="UTF-8"?>
<Music>
<Music_Model>
    <Electronic>Guitar</Electronic>
    <Beats>Pad</Beats>
    <No_of_used>
        <info>4</info>
    </No_of_used>
    <Music_info>
        <Value>1234566</Value>
        <Description>
            <Value>1</Value>
        </Description>
    </Music_info>
</Music_Model>
<Music_Model>
    <Electronic>Piano</Electronic>
    <Beats>Pad</Beats>
    <No_of_used>
        <info>2</info>
    </No_of_used>
</Music_Model>
<Music_Model>
    <Electronic>Guitar123</Electronic>
    <Beats>Flute</Beats>
    <No_of_used>
        <info>3</info>
    </No_of_used>
    <Music_info>
        <Value>128888902</Value>
        <Description>
            <Value>2</Value>
        </Description>
    </Music_info>
</Music_Model>
<Music_Model>
    <Electronic>tabala</Electronic>
    <Beats>Pad</Beats>
    <No_of_used>
        <info>40</info>
    </No_of_used>
    <Music_info>
        <Value>1298932</Value>
    </Music_info>
</Music_Model>
</Music>

注意:在上面输入xml。我感兴趣的是“如果输入 xml 没有 Musci_info 元素并且也有 Music_info 但没有 Description 那么输出 xml 应该使用元素 No_of_used 并且应该只显示它​​的值。如果 Music_info 元素及其值可用,则输出应该是正常的。我可以实现消除但无法获得准确。

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<Music>
<Record>
    <Electronic>Guitar</Electronic>
    <Beats>Pad</Beats>
    <music_info_value>1234566</music_info_value>
    <test_level>1</test_level>
</Record>
<Record>
    <Electronic>Guitar123</Electronic>
    <Beats>Flute</Beats>
    <music_info_value>128888902</music_info_value>
    <test_level>2</test_level>
</Record>
<not_found>
    <product>2</product>
</not_found>
</Music>

输出显示与我工作的代码:

<?xml version="1.0" encoding="UTF-8"?>
<Music>
<Record>
    <Electronic>Guitar</Electronic>
    <Beats>Pad</Beats>
    <music_info_value>1234566</music_info_value>
    <test_level>1</test_level>
</Record>
<Record>
    <Electronic>Guitar123</Electronic>
    <Beats>Flute</Beats>
    <music_info_value>128888902</music_info_value>
    <test_level>2</test_level>
</Record>
<Record>
    <Electronic>tabala</Electronic>
    <Beats>Pad</Beats>
    <music_info_value>1298932</music_info_value>
    <test_level/>
</Record>
<not_found>
    <product>4</product>
</not_found>
<not_found>
    <product>3</product>
</not_found>
<not_found>
    <product>40</product>
</not_found>
 </Music>

我工作的代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <Music>
        <xsl:for-each select="//Music_Model">
            <xsl:if test="//Music_Model/Music_info!=Music_info ">
                <Record>
                    <Electronic>
                        <xsl:value-of select="Electronic"/>
                    </Electronic>
                    <Beats>
                        <xsl:value-of select="Beats"/>
                    </Beats>
                    <music_info_value>
                        <xsl:value-of select="Music_info/Value"/>
                    </music_info_value>
                    <test_level>
                        <xsl:value-of select="Music_info/Description/Value"/>
                    </test_level>
                </Record>
            </xsl:if>
        </xsl:for-each>
        <xsl:for-each select="//Music_Model">
            <xsl:if test="//Music_Model/Music_info!=Music_info">
                <not_found>
                    <product>
                        <xsl:value-of select="No_of_used/info"/>
                    </product>
                </not_found>
            </xsl:if>
        </xsl:for-each>
    </Music>
</xsl:template>

【问题讨论】:

    标签: xml xslt xml-serialization xslt-1.0 xslt-2.0


    【解决方案1】:

    这是一个更简单的推送样式样式表。

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">
     <Music>
       <xsl:apply-templates select="*/Music_Model[    Music_info/Description ]"/>
       <xsl:apply-templates select="*/Music_Model[not(Music_info/Description)]"/>
     </Music>
    </xsl:template>
    
    <xsl:template match="Music_Model">  
     <Record> 
      <xsl:copy-of select="Electronic|Beats"/> 
      <music_info_value><xsl:value-of select="Music_info/Value" /></music_info_value>
      <test_level><xsl:value-of select="Music_info/Description/Value" /></test_level>
     </Record>  
    </xsl:template>
    
    <xsl:template match="Music_Model[not(Music_info/Description)]">  
     <not_found>
       <product><xsl:value-of select="No_of_used/info" /></product>
     </not_found>
    </xsl:template>
    
    </xsl:stylesheet>
    

    这会根据您的要求产生输出,最后是 节点。

    <Music>
      <Record>
        <Electronic>Guitar</Electronic>
        <Beats>Pad</Beats>
        <music_info_value>1234566</music_info_value>
        <test_level>1</test_level>
      </Record>
      <Record>
        <Electronic>Guitar123</Electronic>
        <Beats>Flute</Beats>
        <music_info_value>128888902</music_info_value>
        <test_level>2</test_level>
      </Record>
      <not_found>
        <product>2</product>
      </not_found>
      <not_found>
        <product>40</product>
      </not_found>
    </Music>
    

    注意

    请注意,tabala(产品 40)包含在 not_found 列表中,因为正如您的规则所述,它没有描述。

    【讨论】:

    • 谢谢杜尔金。通过您的示例,我已经清楚地了解了模板的工作原理。我将学习将代码嵌入到单个逻辑中。
    【解决方案2】:

    如果你只是在一个循环中检查 Music_Info/Description 的存在,它会告诉你是否应该输出未找到,所以这样:

    <xsl:template match="/">
        <Music>
            <xsl:for-each select="//Music_Model">
                <xsl:choose>
                    <xsl:when test="Music_info/Description">
                        <Record>
                            <Electronic>
                                <xsl:value-of select="Electronic"/>
                            </Electronic>
                            <Beats>
                                <xsl:value-of select="Beats"/>
                            </Beats>
                            <music_info_value>
                                <xsl:value-of select="Music_info/Value"/>
                            </music_info_value>
                            <test_level>
                                <xsl:value-of select="Music_info/Description/Value"/>
                            </test_level>
                        </Record>
                    </xsl:when>
                    <xsl:otherwise>
                        <not_found>
                            <product>
                                <xsl:value-of select="No_of_used/info"/>
                            </product>
                        </not_found>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </Music>
    </xsl:template>
    

    当应用于您的数据时,会产生以下输出:

    <Music>
        <Record>
            <Electronic>Guitar</Electronic>
            <Beats>Pad</Beats>
            <music_info_value>1234566</music_info_value>
            <test_level>1</test_level>
        </Record>
        <not_found>
            <product>2</product>
        </not_found>
        <Record>
            <Electronic>Guitar123</Electronic>
            <Beats>Flute</Beats>
            <music_info_value>128888902</music_info_value>
            <test_level>2</test_level>
        </Record>
        <not_found>
            <product>40</product>
        </not_found>
    </Music>
    

    这似乎是你想要的

    【讨论】:

    • 根据我对 OP 要求的理解,这是错误的。根据提供的预期输出,not_found 节点应该是最后的,而不是散布的。
    • 感谢 Woody,答案格式不准确,但产生了预期的输出。
    • @WOODY:实时,我想当我们考虑成本基础和使用 Java Beans 处理的时间时,你的逻辑会正常工作。
    • 是的,我没有意识到这个顺序很重要,所以我只是按照它来的顺序做了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    相关资源
    最近更新 更多