使用XSLT转换XML - 检查它是true还是false然后将其转换为Y或N.

时间:2015-04-24 16:05:15

标签: xslt

<Employees xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ListItems>
    <Employee>
      <EmployeeNo>123456</EmployeeNo>
      <FirstName>firstName</FirstName>
      <LastName>lastName</LastName>
      <Email>firstName.lastName@domain.com</Email>
      <Active>true</Active>
    </Employee>
  </ListItems>
</Employees>

XSLT

<xsl:template match="Employee[count(descendant::Active[. = '']) = 1]">
   <xsl:variable name="Active">
      <!--<xsl:for-each select="Employees/ListItems/Employee">-->
      <xsl:choose>
         <xsl:when test="Active='true'">
            <Active>Y</Active>
         </xsl:when>
         <xsl:otherwise>
            <Active>N</Active>
         </xsl:otherwise>
      </xsl:choose>
      <!--</xsl:for-each>-->
   </xsl:variable>
</xsl:template>

当员工的记录Active = true时,我需要写一个xslt,我需要将true转换为“Y”,如果不是那么“N”。我写了这个XSLT,但它无法正常工作

目前= true 我需要的是= Y

3 个答案:

答案 0 :(得分:2)

您希望修改<Active>个节点,具体而言。

因此,只为他们编写模板,让身份模板处理所有其他节点:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />

  <!-- <Active> with a value of 'true': switch value to 'Y' -->
  <xsl:template match="Employee//Active[. = 'true']">
    <xsl:copy>Y</xsl:copy>
  </xsl:template>

  <!-- <Active> with any other value: switch value to 'N' -->
  <xsl:template match="Employee//Active[. != 'true']">
    <xsl:copy>N</xsl:copy>
  </xsl:template>

  <!-- identity template - copy all nodes that have no better template -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:transform>

结果:

<Employees xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ListItems>
      <Employee>
         <EmployeeNo>123456</EmployeeNo>
         <FirstName>firstName</FirstName>
         <LastName>lastName</LastName>
         <Email>firstName.lastName@domain.com</Email>
         <Active>Y</Active>
      </Employee>
  </ListItems>
</Employees>

答案 1 :(得分:1)

要简化此事,请尝试以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="Active">
    <xsl:copy>
        <xsl:choose>
            <xsl:when test=".='true'">Y</xsl:when>
            <xsl:otherwise>N</xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

P.S。此解决方案自豪地使用xsl:choosexsl:choose是XSLT语言不可或缺的一部分,使用它充分利用它绝对没有错。它增加了代码的清晰度,而人工尝试避免使用它只会不必要地混淆代码。

答案 2 :(得分:0)

这个简短而简单的转换(只有两个模板,没有明确的条件说明,没有重复<xsl:copy>,没有<xsl:choose><xsl:when>或{{1} }):

<xsl:otherwise>

应用于以下源XML文档

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

  <xsl:template match="Employee/Active/text()">
     <xsl:value-of select="substring('YN', 2 - (.= 'true'), 1)"/>
  </xsl:template>

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

生成想要的正确结果

<Employees>
    <ListItems>
        <Employee>
            <EmployeeNo>123456</EmployeeNo>
            <FirstName>firstName</FirstName>
            <LastName>lastName</LastName>
            <Email>firstName.lastName@domain.com</Email>
            <Active>true</Active>
        </Employee>
        <Employee>
            <EmployeeNo>234567</EmployeeNo>
            <FirstName>firstName2</FirstName>
            <LastName>lastName2</LastName>
            <Email>firstName.lastName@domain.com</Email>
            <Active>not-quite-true</Active>
        </Employee>
    </ListItems>
</Employees>

<强>解释

  1. 除非覆盖,否则身份规则会将每个节点复制到输出&#34; as as is &#34;
  2. 只有一个其他模板,它会覆盖任何文本节点的标识规则,该文本节点是<Employees> <ListItems> <Employee> <EmployeeNo>123456</EmployeeNo> <FirstName>firstName</FirstName> <LastName>lastName</LastName> <Email>firstName.lastName@domain.com</Email> <Active>Y</Active> </Employee> <Employee> <EmployeeNo>234567</EmployeeNo> <FirstName>firstName2</FirstName> <LastName>lastName2</LastName> <Email>firstName.lastName@domain.com</Email> <Active>N</Active> </Employee> </ListItems> </Employees> 元素的子元素,它是Active元素的子元素
  3. 后一个模板输出字符串Employee的子字符串,长度为1,偏移量由'YN'确定 - 我们在XPath 1.0中使用的事实是布尔值是算术的参数操作,2 - (.= 'true')转换为true()1转换为false()