使用XSLT的XML自定义转换

使用XSLT的XML自定义转换,xml,xslt,xpath,Xml,Xslt,Xpath,我输入了XML <?xml version="1.0" encoding="UTF-8"?> <Vehicle> <Ordinary> <Car>Honda City</Car> </Ordinary> <Luxury> <Car>Volkswagon</Car> </Luxury> <Luxury> <Car>Dzire

我输入了XML

<?xml version="1.0" encoding="UTF-8"?>
<Vehicle>
<Ordinary>
    <Car>Honda City</Car>
</Ordinary> 
<Luxury>
    <Car>Volkswagon</Car>
</Luxury>   
<Luxury>
    <Car>Dzire</Car>
</Luxury>

本田思迪
福士
迪泽尔

我必须使用XSLT将此xml消息转换为

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<id>1</id>
<title>/Vehicle/Ordinary/</title>
<text>Car</text>
<answer>Honda City</answer>
</item>
<item>
<id>2</id>
<title>/Vehicle/Luxury[1]/</title>
<text>Car</text>
<answer>Volkswagon</answer>
</item>
<item>
<id>3</id>
<title>/Vehicle/Luxury[2]/</title>
<text>Car</text>
<answer>Dzire</answer>
</item>

1.
/车辆/普通/
汽车
本田思迪
2.
/车辆/豪华车[1]/
汽车
福士
3.
/车辆/豪华车[2]/
汽车
迪泽尔

  • 此处id可以是自动生成的唯一编号
  • 所有不包含任何值的父标记Xpath都将位于标记内部
  • 具有值的元素位于标记内部
  • 实际值位于标记内
  • XSLT应该足够通用,可以应用任何XML文档格式&而不是特定于给定的示例XML
我从下面开始

<?xml version="1.0" encoding="windows-1252" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:strip-space elements = "*" />
<xsl:template match="/">
<items>
<xsl:apply-templates/>
</items>
</xsl:template>
<xsl:template match="text()">
<item>      
<title>
<xsl:for-each select="ancestor-or-self::*">
<xsl:text>/</xsl:text>
<xsl:value-of select="name()" />
</xsl:for-each>
</title>    
<answer>
<xsl:value-of select="." />
<xsl:apply-templates/>
</answer>
</item>
</xsl:template>
</xsl:stylesheet>    

/
它的产量低于产量

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<id>1</id>
<title>/Vehicle/Ordinary/Car</title>
<answer>Honda City</answer>
</item>
<item>
<id>2</id>
<title>/Vehicle/Luxury[1]/Car</title>   
<answer>Volkswagon</answer>
</item>
<item>
<id>2</id>
<title>/Vehicle/Luxury[2]/Car</title>   
<answer>Dzire</answer>
</item>
</items>    

1.
/车辆/普通/汽车
本田思迪
2.
/车辆/豪华车[1]/汽车
福士
2.
/车辆/豪华车[2]/汽车
迪泽尔
需要你的帮助

此处id可以是自动生成的唯一编号

我会使用
generate-id()
来获得唯一的id

所有不包含任何值的父标记Xpath都将包含在内
标签

根据您的目标输出,除了第一个祖先之外,您似乎还需要其他祖先

具有值的元素位于
标记内

只需使用父级的
name()

实际值位于
标记内

看来你已经搞定了

例如

XSLT1.0

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

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

  <xsl:template match="text()">
    <item>
      <id><xsl:value-of select="generate-id()"/></id>
      <title>
        <xsl:for-each select="ancestor::*[position()>1]">
          <xsl:value-of select="concat('/',name())"/>
          <xsl:if test="(preceding-sibling::*|
            following-sibling::*)[name()=name(current())]">
            <xsl:value-of select="concat('[',
              count(preceding-sibling::*[name()=name(current())])+1,
              ']')"/>
          </xsl:if>
        </xsl:for-each>
        <xsl:text>/</xsl:text>
      </title>
      <text><xsl:value-of select="name(..)"/></text>
      <answer>
        <xsl:value-of select="." />
        <xsl:apply-templates/>
      </answer>
    </item>
  </xsl:template>
</xsl:stylesheet>

/
输出

<items>
   <item>
      <id>d0t4</id>
      <title>/Vehicle/Ordinary/</title>
      <text>Car</text>
      <answer>Honda City</answer>
   </item>
   <item>
      <id>d0t7</id>
      <title>/Vehicle/Luxury[1]/</title>
      <text>Car</text>
      <answer>Volkswagon</answer>
   </item>
   <item>
      <id>d0t10</id>
      <title>/Vehicle/Luxury[2]/</title>
      <text>Car</text>
      <answer>Dzire</answer>
   </item>
</items>

d0t4
/车辆/普通/
汽车
本田思迪
d0t7
/车辆/豪华车[1]/
汽车
福士
d0t10
/车辆/豪华车[2]/
汽车
迪泽尔

您已经向我们提供了要求,但您没有向我们展示您的尝试或您遇到的问题。没有实际问题。这看起来更像是一个请求。@Daniel:添加了我用来启动转换的XSLT“XSLT应该足够通用,可以应用任何XML文档格式”,没有这样的东西。XML非常灵活,一个XSLT不可能处理任何XML模式,除非处理完全没有意义(例如身份转换)<代码>生成-id()不能保证这一点(正如您的输出所示)。一种可能是对前面的车辆节点进行计数:
@ABach-True,不能保证它是一个数字,但可以保证它是唯一的,而计数前面的同级节点不能保证它是唯一的。有没有办法为id生成唯一的有序序列号?我不希望id中有任何字符。@MaheshB-我会将
替换为
@Daniel-上述解决方案不会在级别上创建索引。考虑一下XML,本田