XSLT For-Each循环从枚举标记中获取数据? [英] XSLT For-Each loop to get data from enumerated tags?

查看:170
本文介绍了XSLT For-Each循环从枚举标记中获取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经提供了一个SML文件,设计者(不在我的公司,所以我无法控制这个)创建了一些我需要使用的数据;但他们设置枚举标签,所以我很难创建一个循环来读取数据。

它们的代码看起来像

 < Root> 
<科目>
< ...更多XML数据>
< Data>
< ...其他XML数据>
< Demographic_Information>
< Age1> 33< / Age1>
< Age2> 66< / Age2>
< Age3 />
< Age4 />
< Age5 />
< Age6 />
< Age7 />
< Age8 />
< Age9 />
< Age10 />
< Gender1> M< / Gender1>
< Gender2> F< / Gender2>
< Gender3 />
< Gender4 />
< Gender5 />
< Gender6 />
< Gender7 />
< Gender8 />
< Gender9 />
< Gender10 />
< Race1> W< / Race1>
< Race2> H< / Race2>
< Race3 />
< Race4 />
< Race5 />
< Race6 />
< Race7 />
< Race8 />
< Race9 />
< Race10 />
< / Demographic_Information>
< / ...其他XML数据>
< / Data>
< / ...更多XML数据>
< /科目>
< / Root>

我只需循环执行此操作,并确保Age1,Gender1和Race1进入我的数据像

 < Person subject =1> 
<年龄> 33< /年龄>
<性别> M< /性别>
< Race> W< / Race>
< / Person>
< Person subject =2>
<年龄> 66< /年龄>
<性别> F< /性别>
< Race> A< / Race>
< / Person>

这是更大集合中数据的一个子集,但是我需要把它变成这种格式if可能。我相信它可以做,我只是不知道如何去做。



我的XSLT是Microsoft Visual Studio 2008中的1.0版。我以

 < xsl:template match =/ Root / Subjects> 

***修改后可以提供我的问题的更好的示例。

解决方案

下面是一个快速的刺法 - 我将继续看这个来找到效率,但我想给你一个答案。 >

编辑:感谢@MartinHonnen提供了一个很好的简化。

XSLT:

 <?xml version =1.0encoding =UTF-8?> 
< xsl:stylesheet xmlns:xsl =http://www.w3.org/1999/XSL/Transformversion =1.0>
< xsl:output omit-xml-declaration =yesindent =yes/>
< xsl:strip-space elements =*/>

< xsl:variable
name =vNums
select ='0123456789'/>

name =kElemByNumber
match =Demographic_Information / *
use =translate(name(),translate(name ),$ vNums,''),'')/>

< xsl:template match =/ *>
< Demographic_Information>
< xsl:apply-templates
select =* [generate-id()=
generate-id(key(
'kElemByNumber',
translate name(),translate(name(),$ vNums,''),
''
))[1])] [normalize-space()]>
select =translate(name(),translate(name(),$ vNums,''),'')
data-type =number />
< / xsl:apply-templates>
< / Demographic_Information>
< / xsl:template>

< xsl:template match =*>
< Person subject ={position()}>
select =key('kElemByNumber',position())
mode =children>
< xsl:sort select =name()/>
< / xsl:apply-templates>
< / Person>
< / xsl:template>

< xsl:template match =*mode =children>
< xsl:apply-templates />
< / xsl:element>
< / xsl:template>
< / xsl:stylesheet>

...应用于提供的源XML:

 < Demographic_Information> 
< Age1> 33< / Age1>
< Age2> 66< / Age2>
< Age3 />
< Age4 />
< Age5 />
< Age6 />
< Age7 />
< Age8 />
< Age9 />
< Age10 />
< Gender1> M< / Gender1>
< Gender2> F< / Gender2>
< Gender3 />
< Gender4 />
< Gender5 />
< Gender6 />
< Gender7 />
< Gender8 />
< Gender9 />
< Gender10 />
< Race1> W< / Race1>
< Race2> H< / Race2>
< Race3 />
< Race4 />
< Race5 />
< Race6 />
< Race7 />
< Race8 />
< Race9 />
< Race10 />
< / Demographic_Information>

...想要的结果是产生的:

 < Demographic_Information> 
< Person subject =1>
<年龄> 33< /年龄>
<性别> M< /性别>
< Race> W< / Race>
< / Person>
< Person subject =2>
<年龄> 66< /年龄>
<性别> F< /性别>
< Race> A< / Race>
< / Person>
< / Demographic_Information>


I've been provided an SML file where the designer (not in my company, so I have no control over this) has created some data that I need to consume; but they setup enumerated tags, so I'm having a difficult time creating a loop to read the data.

Their code looks like

   <Root>
    <Subjects>
    <...more XML Data>
    <Data>
      <...other XML Data>
      <Demographic_Information>
            <Age1>33</Age1>
            <Age2>66</Age2>
            <Age3 />
            <Age4 />
            <Age5 />
            <Age6 />
            <Age7 />
            <Age8 />
            <Age9 />
            <Age10 />
            <Gender1>M</Gender1>
            <Gender2>F</Gender2>
            <Gender3 />
            <Gender4 />
            <Gender5 />
            <Gender6 />
            <Gender7 />
            <Gender8 />
            <Gender9 />
            <Gender10 />
            <Race1>W</Race1>
            <Race2>H</Race2>
            <Race3 />
            <Race4 />
            <Race5 />
            <Race6 />
            <Race7 />
            <Race8 />
            <Race9 />
            <Race10 />
        </Demographic_Information>
        </...other XML Data>
    </Data>
    </...more XML Data>
   </Subjects>
  </Root>

I just need to loop through this, and ensure that Age1, Gender1, and Race1 go into my data like

<Person subject="1">
    <Age>33</Age>
    <Gender>M</Gender>
    <Race>W</Race>
</Person>
<Person subject="2">
    <Age>66</Age>
    <Gender>F</Gender>
    <Race>A</Race>
</Person>

This is a subset of data inside a larger set, but I need to get it into this format if possible. I'm sure it can be done, I just don't know how to go about it.

My XSLT is version 1.0 in Microsoft Visual Studio 2008. I start with

<xsl:template match="/Root/Subjects">

***Modified to provide a better sample of my issue.

解决方案

Here's a quick stab that works - I'm going to continue to look at this to find efficiencies, but I wanted to get you an answer.

EDIT: thanks to @MartinHonnen for a nice simplification.

When this XSLT:

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

  <xsl:variable
     name="vNums"
     select="'0123456789'"/>

  <xsl:key
     name="kElemByNumber"
     match="Demographic_Information/*"
     use="translate(name(), translate(name(), $vNums, ''), '')"/>

  <xsl:template match="/*">
    <Demographic_Information>
      <xsl:apply-templates 
        select="*[generate-id() = 
                  generate-id(key(
                    'kElemByNumber',
                    translate(name(), translate(name(), $vNums, ''),
                    ''
                  ))[1])][normalize-space()]">
        <xsl:sort
          select="translate(name(), translate(name(), $vNums, ''), '')"
          data-type="number"/>
      </xsl:apply-templates>
    </Demographic_Information>
  </xsl:template>

  <xsl:template match="*">
    <Person subject="{position()}">
      <xsl:apply-templates
        select="key('kElemByNumber', position())"
        mode="children">
        <xsl:sort select="name()"/>
      </xsl:apply-templates>
    </Person>
  </xsl:template>

  <xsl:template match="*" mode="children">
    <xsl:element name="{translate(name(), $vNums, '')}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

...is applied to the provided source XML:

<Demographic_Information>
  <Age1>33</Age1>
  <Age2>66</Age2>
  <Age3/>
  <Age4/>
  <Age5/>
  <Age6/>
  <Age7/>
  <Age8/>
  <Age9/>
  <Age10/>
  <Gender1>M</Gender1>
  <Gender2>F</Gender2>
  <Gender3/>
  <Gender4/>
  <Gender5/>
  <Gender6/>
  <Gender7/>
  <Gender8/>
  <Gender9/>
  <Gender10/>
  <Race1>W</Race1>
  <Race2>H</Race2>
  <Race3/>
  <Race4/>
  <Race5/>
  <Race6/>
  <Race7/>
  <Race8/>
  <Race9/>
  <Race10/>
</Demographic_Information>

...the wanted result is produced:

<Demographic_Information>
  <Person subject="1">
    <Age>33</Age>
    <Gender>M</Gender>
    <Race>W</Race>
  </Person>
  <Person subject="2">
    <Age>66</Age>
    <Gender>F</Gender>
    <Race>A</Race>
  </Person>
</Demographic_Information>

这篇关于XSLT For-Each循环从枚举标记中获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆