【问题标题】:XML Customized transformation using XSLT使用 XSLT 的 XML 自定义转换
【发布时间】:2017-04-12 15:25:07
【问题描述】:

我已经输入了 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>

  • 这里的 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>    

需要你的帮助...

【问题讨论】:

  • 您已经向我们提供了要求,但您没有向我们展示您尝试了什么或遇到了问题。没有实际的问题。这似乎更像是一个"Do you haz teh codez?" 请求。
  • @Daniel : 添加了我用来启动转换的 XSLT
  • "XSLT 应该足够通用,可以应用任何格式的 XML 文档" 没有这样的东西。 XML 非常灵活,一个 XSLT 不可能处理任何 XML 模式 - 除非处理完全没有意义(例如身份转换)。

标签: xml xslt xpath


【解决方案1】:

这里的 id 可以是自动生成的唯一编号..

我会使用 generate-id() 来获取唯一的 ID。

所有没有任何值的父标签Xpath都会进来 &lt;title&gt; 标签。

根据您的目标输出,您似乎想要除第一个之外的祖先。

具有价值的元素进入&lt;text&gt;标签内。

只需使用父级的name()

实际值在&lt;answer&gt;标签内。

看起来你已经知道了。

示例...

XSLT 1.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>

【讨论】:

  • OP 提到希望&lt;id&gt; 是一个唯一的、自动生成的号码generate-id() 不保证这一点(如您的输出所示)。一种可能性是计算前面的车辆节点:&lt;id&gt;&lt;xsl:value-of select="count(preceding-sibling::*) + 1"/&gt;&lt;/id&gt;
  • @ABach - 是的,它不保证是一个数字,但它保证是唯一的,计算前面的兄弟姐妹并不能保证。
  • 有没有办法为id生成唯一的有序序列号?我不想要任何 id 字符。
  • @MaheshB - 我会将&lt;xsl:value-of select="generate-id()"/&gt; 替换为&lt;xsl:number level="any"/&gt;
  • @Daniel - 上述解决方案不会在 级别创建索引。考虑xml,VolkswagonDzireHonda City
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多