在XSLT 2.0中获取重复元素,几乎没有元素转换

时间:2017-05-16 14:40:13

标签: xml xslt xslt-2.0

关于重复元素以及如何使用xsl身份模板,我经历了很少的线程。但我的要求是重复大部分需要转换的字段。

以下是我的意见:

<?xml version="1.0" encoding="UTF-8"?>
<Roots xmlns="urn:com.mydish/extps">
    <Root>
        <Worker>100</Worker>
        <Group></Group>
        <Amount>1165851.81</Amount>
        <Currency>USD</Currency>
        <Check>201705091204</Check>
        <File_Name>1.pdf</File_Name>
    </Root>
     <Root>
        <Worker>20</Worker>
        <Group></Group>
        <Amount>231456.41</Amount>
        <Currency>USD</Currency>
        <Check>201705091204</Check>
        <File_Name>2.pdf</File_Name>
    </Root>
 </Roots>

输出必须是:

<?xml version="1.0" encoding="UTF-8"?>
<Roots xmlns="urn:com.mydish/extps">
    <Root>
        <Worker>C10</Worker>
        <Group>Group1</Group>
        <Amount>1165851.81</Amount>
        <Currency>USD</Currency>
        <Check>201705091204</Check>
        <File_Name>1.pdf</File_Name>
    </Root>
     <Root>
        <Worker>C20</Worker>
        <Group>Group2</Group>
        <Amount>231456.41</Amount>
        <Currency>USD</Currency>
        <Check>201705091204</Check>
        <File_Name>2.pdf</File_Name>
    </Root>
 </Roots>

因此,逻辑依赖于输入Worker的长度,输出要转换的Worker和Group字段。

如果输入工作者的长度为3位,则输出工作者将为C且前两位数(C10)和组将为Group1。如果输入工作长度是2位数,那么然后将C连接到输出Worker(C20),Group将是Group2。

休息必须与输入相同。

如何改变这个? 以下是对的吗?我知道这不会按原样运作。

<Worker>
    <xsl:value-of select="if string-length(Worker)='3' then concat('C',substring(Worker,1,2)) else concat('C',Worker)" />
</Worker>
<Group>
     <xsl:value-of select="if string-length(Worker)='3' then 'Group1' else 'Group2'" />
</Group>    

2 个答案:

答案 0 :(得分:0)

尝试以下脚本:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="urn:com.mydish/extps"
  xpath-default-namespace="urn:com.mydish/extps">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="Worker">
    <xsl:copy>
      <xsl:value-of select="if (string-length() = 3)
        then concat('C', substring(., 1, 2))
        else concat('C', .)" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Group">
    <xsl:copy>
      <xsl:value-of select="if (string-length(../Worker) = 3)
        then 'Group1' else 'Group2'" />
    </xsl:copy>
  </xsl:template>

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

你非常接近正确的解决方案。

我添加了名称空间处理并对您的代码进行了细微更改。

也许你应该阅读一些内容来学习:

  • 关于命名空间处理,
  • XPath 表达式设置默认命名空间
  • 模板中的当前对象.)的概念 它的价值是什么,
  • 如何引用兄弟对象(例如 Worker 元素 来自 Group 模板。

答案 1 :(得分:0)

对于/api/gift-shop,你可以做到:

Worker

对于<xsl:template match="Worker"> <xsl:copy> <xsl:text>C</xsl:text> <xsl:value-of select="substring(., 1, 2)"/> </xsl:copy> </xsl:template> ,您只需要进行一些语法更正:

Group

当然,这是身份转换模板的补充。