首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过XSL将一种XML格式转换为另一种格式

通过XSL将一种XML格式转换为另一种格式
EN

Stack Overflow用户
提问于 2009-07-22 16:52:55
回答 1查看 784关注 0票数 0

现有格式为

代码语言:javascript
复制
<A>
  <B>
    <C>hello</C>
    <C>how</C>
    <C>are</C>
    <C>you</C> 
  </B>
</A>

我想把它转换成这样的东西

代码语言:javascript
复制
<start>
  <A>
    <B>
      <tag1> hello </tag1>
      <tag2> hello </tag2>
    </B>
  </A>
  <A>
    <B>
      <tag1> are </tag1>
      <tag2> you </tag2>
    </B>
  </A>
</start>

现在,该<C>标签可以出现n次,并且对于每个2个<C>标签的束,应该创建具有相同标签名称(参见tag1和tag2名称在这两种情况下相同)的新<A> </A>标签。整个过程是动态的。

更新:

我有一个现有的动态XML结构,如下所示

代码语言:javascript
复制
<LSR_RESP>
    <HDR> 
        <ORD>AAAAA</ORD>   
        <ORD>BBBBB</ORD>  
        <ORD>CCCCC</ORD>   
        <ORD>DDDDD</ORD> 
        <ORD>EEEEE</ORD> 
        <ORD>FFFFF</ORD>
        <ORD>GGGGG</ORD>
        <ORD>RRRRR</ORD>
        <ORD>KKKKK</ORD>
    </HDR>
</LSR_RESP>

我想通过XSLT将其转换为如下所示

代码语言:javascript
复制
<entity>
<r>
  <c>
  <f ID="OrderNumber1">AAAAA</f> 
  <f ID="OrderNumber2">BBBBB</f> 
  <f ID="OrderNumber3">CCCCC</f> 
  <f ID="OrderNumber4">DDDDD</f> 
  <f ID="OrderNumber5">EEEEE</f> 
  <f ID="OrderNumber6">FFFFF</f> 
  <f ID="OrderNumber7">GGGGG</f> 
  </c>
  </r>
  <r>
  <c>
  <f ID="OrderNumber1">RRRRR</f> 
  <f ID="OrderNumber2">KKKKK</f> 
  </c>
  </r>
  </entity>

现在,正如你在上面看到的,每行标签都是由7个组中的标签值组成的。新标签的名称也将在7个组中重复出现,比如"OrderNumber1“到"OrderNumber7”。该场可以出现n次,但新结构将以7个为一组形成。

就像上面的例子中的9个标签一样,它形成了2个组,7个组中的一个,留下了(9-7)个标签,即下一个组的2个标签,所以在下一个组中,你只能看到OrderNumber1和OrderNumber2。如果有10个标签,它将是一个7个标签的组,然后是另一个3个标签的组。如果有15个标签,它将是两个7个标签组,然后是另一个1个标签组。

EN

回答 1

Stack Overflow用户

发布于 2009-07-22 16:59:34

最简单的方法(XSLT 1.0已经足够了):

代码语言:javascript
复制
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

<xsl:template match="/">
  <start>
    <xsl:apply-templates select="
      A/B/C[position() mod 2 = 1 and following-sibling::C]" 
    />
  </start>
</xsl:template>

<xsl:template match="C">
  <A>
    <B>
      <tag1>
        <xsl:value-of select="text()" />
      </tag1>
      <tag2>
        <xsl:value-of select="following-sibling::C[1]/text()" />
      </tag2>
    </B>
  </A>
</xsl:template>

</xsl:stylesheet>

也可能,由于使用单独的模板和<xsl:copy>/<xsl:copy-of>,可能会更灵活

代码语言:javascript
复制
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:template match="/">
    <start>
      <xsl:for-each select="
        A/B/C[position() mod 2 = 1 and following-sibling::C]
      ">
        <xsl:apply-templates select="ancestor::A">
          <xsl:with-param name="C" select="." />
        </xsl:apply-templates>
      </xsl:for-each>
    </start>
  </xsl:template>

  <xsl:template match="A">
    <xsl:param name="C" />
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:apply-templates select="B">
        <xsl:with-param name="C" select="$C" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="B">
    <xsl:param name="C" />
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:apply-templates select="$C" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="C">
    <tag1>
      <xsl:value-of select="text()" />
    </tag1>
    <tag2>
      <xsl:value-of select="following-sibling::C[1]/text()" />
    </tag2>
  </xsl:template>

</xsl:stylesheet>

但话又说回来,这可能太复杂了,这取决于你的实际数据。关键点是只选择感兴趣的<C>节点(位于奇数位置的节点),并围绕它们构建其余的转换。

这两个模板都会导致:

代码语言:javascript
复制
<start>
  <A>
    <B>
      <tag1>hello</tag1>
      <tag2>how</tag2>
    </B>
  </A>
  <A>
    <B>
      <tag1>are</tag1>
      <tag2>you</tag2>
    </B>
  </A>
</start>
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1166652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档