我有以下xml代码(简化后,假名始终存在,但患者也可能是另一个内容不同的标签):
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<patient>
<Sexe>V</Sexe>
<yob>1984</yob>
<status>2</status>
</patient>
</Data>
</Record>
我正在寻找xslt解决方案,结果如下:
<Record>
<patient>
<B>e113</B>
<M>lss9</M>
<S>f6rr</S>
<Sexe>V</Sexe>
<yob>1984</yob>
<status>2</status>
</patient>
</Record>
问题是我如何将假名标签和(在这种情况下,患者标签)组合成一条记录。如上所述,这是一个简化的例子。 Patient-tag也可以是同一文档中的其他标签。所以我需要一个通用的解决方案,它将Pseudonyms-tag之后的所有标签与之后的标签前缀(在本例中为Patient)结合起来。
我知道如何将<Pseudonym type="B">e113</Pseudonym>
转换为<B>e113</B>
,但我不知道如何以正确的方式组合标记以获得示例中的结果。
我希望我能够很好地解释我试图帮助的事情。蒂亚。
编辑:
我没有提到的是,患者只是众多不同标签中的一种。所以简短的版本是:
XML
<?xml version="1.0" encoding="UTF-8"?>
<Bestand>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<Patient>
<Sexe>V</Sexe>
<yob>1984</yob>
<status>2</status>
</Patient>
</Data>
</Record>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<SurveyA>
<Item01>1</Item01>
<Item02>4</Item02>
<Item03>8</Item03>
</SurveyA>
</Data>
</Record>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<SurveyB>
<Item01>1</Item01>
<Item02>3</Item02>
<Item03>2</Item03>
</SurveyB>
</Data>
</Record>
</Bestand>
我的xsl看起来像:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:element name="message">
<xsl:apply-templates select="//Data"/>
</xsl:element>
</xsl:template>
<xsl:template match="Patient|SurveyA|SurveyB">
<xsl:element name="{name()}">
<xsl:element name="B"><xsl:value-of select="//Pseudonyms/Pseudonym[@type='B']" /></xsl:element>
<xsl:element name="M"><xsl:value-of select="//Pseudonyms/Pseudonym[@type='M']" /></xsl:element>
<xsl:element name="S"><xsl:value-of select="//Pseudonyms/Pseudonym[@type='S']" /></xsl:element>
<xsl:copy-of select="node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这导致下一个输出是我想要的,但我也想知道会有更好,更清洁的方式。
![Output][1]
[1]: http://i.stack.imgur.com/1Lcea.png
如上所述,这有效,我只剩下一个问题,可能有多个Patient,SurveyA和SurveyB记录。当我应用我的样式表时,整个事情没有排序。因此,可以存在患者记录,然后是SurveyA记录。此SurveyA记录可以依次显示患者记录。如果我可以对特定项目进行分组,那就太好了。这个我还没有能够帮凶。
答案 0 :(得分:1)
这是实现目标的一种方式:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Record">
<Record>
<patient>
<xsl:apply-templates select="Pseudonyms/Pseudonym" />
<xsl:apply-templates select="Data/patient/*" />
</patient>
</Record>
</xsl:template>
<xsl:template match="Pseudonym">
<xsl:element name="{@type}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
这是一个类似于四十二个答案的选项,但考虑到了您的更新问题。
注意:
Pseudonym
对@type
进行排序。如果这不是必要的,只需删除xsl:sort
。Pseudonym
元素的转换。如果它们与问题中显示的一样静态,您可以返回使用xsl:value-of
对元素进行硬编码。 (但您不需要使用xsl:element
。XML输入(略微修改以显示排序)
<Bestand>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113a</Pseudonym>
<Pseudonym type="M">lss9a</Pseudonym>
<Pseudonym type="S">f6rra</Pseudonym>
</Pseudonyms>
<Data>
<Patient>
<Sexe>V</Sexe>
<yob>1984</yob>
<status>2</status>
</Patient>
</Data>
</Record>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<SurveyA>
<Item01>1</Item01>
<Item02>4</Item02>
<Item03>8</Item03>
</SurveyA>
</Data>
</Record>
<Record>
<Pseudonyms>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<Patient>
<Sexe>W</Sexe>
<yob>1985</yob>
<status>3</status>
</Patient>
</Data>
</Record>
<Record>
<Pseudonyms>
<Pseudonym type="B">e113</Pseudonym>
<Pseudonym type="M">lss9</Pseudonym>
<Pseudonym type="S">f6rr</Pseudonym>
</Pseudonyms>
<Data>
<SurveyB>
<Item01>1</Item01>
<Item02>3</Item02>
<Item03>2</Item03>
</SurveyB>
</Data>
</Record>
</Bestand>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<message>
<xsl:apply-templates select="Record/Data/*">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</message>
</xsl:template>
<xsl:template match="Data/*">
<xsl:copy>
<xsl:apply-templates select="../../Pseudonyms/Pseudonym">
<xsl:sort select="@type"/>
</xsl:apply-templates>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Pseudonym">
<xsl:element name="{@type}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML输出
<message>
<Patient>
<B>e113a</B>
<M>lss9a</M>
<S>f6rra</S>
<Sexe>V</Sexe>
<yob>1984</yob>
<status>2</status>
</Patient>
<Patient>
<B>e113</B>
<M>lss9</M>
<S>f6rr</S>
<Sexe>W</Sexe>
<yob>1985</yob>
<status>3</status>
</Patient>
<SurveyA>
<B>e113</B>
<M>lss9</M>
<S>f6rr</S>
<Item01>1</Item01>
<Item02>4</Item02>
<Item03>8</Item03>
</SurveyA>
<SurveyB>
<B>e113</B>
<M>lss9</M>
<S>f6rr</S>
<Item01>1</Item01>
<Item02>3</Item02>
<Item03>2</Item03>
</SurveyB>
</message>