如何在XSLT中为单个for-each选择多个节点

时间:2010-05-05 17:30:59

标签: xslt

我正在尝试学习XSLT,但我最好通过示例。我想对模式转换执行一个简单的模式。如何仅在一次传递中执行此转换(我当前的解决方案使用两次传递并丢失原始客户订单)?

自:

<?xml version="1.0" encoding="UTF-8"?>
<sampleroot>

<badcustomer>
    <name>Donald</name>
    <address>Hong Kong</address>
    <age>72</age>
</badcustomer>

<goodcustomer>
    <name>Jim</name>
    <address>Wales</address>
    <age>22</age>
</goodcustomer>

<goodcustomer>
    <name>Albert</name>
    <address>France</address>
    <age>51</age>
</goodcustomer>

</sampleroot>

致:

<?xml version="1.0" encoding="UTF-8"?>
<records>

<record id="customer">
    <name>Donald</name>
    <address>Hong Kong</address>
    <age>72</age>
    <customertype>bad</customertype>
</record>

<record id="customer">
    <name>Jim</name>
    <address>Wales</address>
    <age>22</age>
    <customertype>good</customertype>
</record>

<record id="customer">
    <name>Albert</name>
    <address>France</address>
    <age>51</age>
    <customertype>good</customertype>
</record>

</records>

我已经解决了这个 的方式(我失去了客户的订单,我认为我必须多次解析文件:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/sampleroot">

    <records>

        <xsl:for-each select="goodcustomer">
            <record id="customer">
                <name><xsl:value-of select="name" /></name>
                <address><xsl:value-of select="address" /></address>
                <age><xsl:value-of select="age" /></age>
                <customertype>good</customertype>
            </record>
        </xsl:for-each>

        <xsl:for-each select="badcustomer">
            <record id="customer">
                <name><xsl:value-of select="name" /></name>
                <address><xsl:value-of select="address" /></address>
                <age><xsl:value-of select="age" /></age>
                <customertype>bad</customertype>
            </record>
        </xsl:for-each>

    </records>
    </xsl:template>
</xsl:stylesheet>

请有人帮我解决正确的XSLT构造,我只需要使用一个解析(每个只有一个)吗?

谢谢,

克里斯

1 个答案:

答案 0 :(得分:7)

避免尽可能使用<xsl:for-each> 是一种很好的XSLT做法。

这是一个简单的解决方案,使用此原则

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <records>
    <xsl:apply-templates/>
  </records>
 </xsl:template>

 <xsl:template match="badcustomer | goodcustomer">
  <record>
   <xsl:apply-templates/>
   <customertype>
     <xsl:value-of select="substring-before(name(), 'customer')"/>
   </customertype>
  </record>
 </xsl:template>
</xsl:stylesheet>

请注意

  1. 仅使用模板和<xsl:apply-templates>

  2. 在必要时使用身份规则及其覆盖。这是最基本的XSLT设计模式之一。