不寻常的XSLT转换—XML的结构化
我有一些不寻常的问题。我的任务是“结构化XML”。这是一个输入XML(示例):不寻常的XSLT转换—XML的结构化,xml,xslt,transformation,Xml,Xslt,Transformation,我有一些不寻常的问题。我的任务是“结构化XML”。这是一个输入XML(示例): 复习 第1版 术语表 10 文件中使用的术语 学期 沙特阿拉伯 某些属性 SOA 其他属性 接口 AC-163 术语表 15 另一项 学期 名称#1 附件1 姓名#2 附件2 我应该做的是将其转换为以下实体结构: 文档1..*文档1..1项目1..*项目1..1属性1..*属性 这意味着:元素“documents”可能包含许多“document”,“document”只包含一个名为“items”的元素,“item
复习
第1版
术语表
10
文件中使用的术语
学期
沙特阿拉伯
某些属性
SOA
其他属性
接口
AC-163
术语表
15
另一项
学期
名称#1
附件1
姓名#2
附件2
我应该做的是将其转换为以下实体结构:
文档1..*文档1..1项目1..*项目1..1属性1..*属性
这意味着:元素“documents”可能包含许多“document”,“document”只包含一个名为“items”的元素,“items”可能包含许多元素“item”,等等
上述示例的预期输出为:
<documents>
<document>
<document_id>REV#1</document_id>
<items>
<item>
<id>10</id>
<description>Terms used in documents</description>
<attributes>
<attribute>
<name>SA</name>
<value>Some Attribute</value>
</attribute>
<attribute>
<name>SOA</name>
<value>Some Other Attribute</value>
</attribute>
</attributes>
</item>
</items>
</document>
<document>
<document_id>AC-163</document_id>
<items>
<item>
<id>15</id>
<description>Another item</description>
<attributes>
<attribute>
<name>Name#1</name>
<value>Att#1</value>
</attribute>
<attribute>
<name>Name#2</name>
<value>Att#2</value>
</attribute>
</attributes>
</item>
</items>
</document>
</documents>
第1版
10
文件中使用的术语
沙特阿拉伯
某些属性
SOA
其他属性
AC-163
15
另一项
名称#1
附件1
姓名#2
附件2
在这项任务中我需要一些麻烦。。。。我可以请你帮忙吗?这对于“结构化”xml来说是不寻常的——你有什么想法吗
致以最良好的祝愿 如果您使用的是XSLT 2.0,这应该很容易实现,但为了防止您被XSLT 1.0困住,这里有一个与XSLT 1.0兼容的解决方案 样式表
输入
复习
第1版
术语表
10
文件中使用的术语
学期
沙特阿拉伯
某些属性
SOA
其他属性
接口
AC-163
术语表
15
另一项
学期
名称#1
附件1
姓名#2
附件2
输出
第1版
10
文件中使用的术语
沙特阿拉伯
某些属性
SOA
其他属性
AC-163
15
另一项
名称#1
附件1
姓名#2
附件2
我称之为“同级递归”技术的一个很好的例子。但是XSLT2.0位置分组更容易…@michael kay:谢谢!完全同意XSLT 2.0分组更容易-我只是选择XSLT 1.0,因为问题中没有指定XSLT版本。它是有效的,但为什么您认为“Items”只包含一个“Item”,等等(我修改了我的答案,以便在下一个
元素之前考虑以下多个
同级元素。
<documents>
<document>
<document_id>REV#1</document_id>
<items>
<item>
<id>10</id>
<description>Terms used in documents</description>
<attributes>
<attribute>
<name>SA</name>
<value>Some Attribute</value>
</attribute>
<attribute>
<name>SOA</name>
<value>Some Other Attribute</value>
</attribute>
</attributes>
</item>
</items>
</document>
<document>
<document_id>AC-163</document_id>
<items>
<item>
<id>15</id>
<description>Another item</description>
<attributes>
<attribute>
<name>Name#1</name>
<value>Att#1</value>
</attribute>
<attribute>
<name>Name#2</name>
<value>Att#2</value>
</attribute>
</attributes>
</item>
</items>
</document>
</documents>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- Identity transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="document">
<!-- Store the unique ID of the current element into a variable. -->
<xsl:variable name="id" select="generate-id()"/>
<xsl:copy>
<xsl:apply-templates select="following-sibling::document_id[1]"/>
<items>
<!--
Apply all <item_attribute_name> elements whose first preceding
<document> sibling is the element that's currently being processed. This
is to keep from processing *all* of the rest of the
<item_attribute_name> elements in the document.
-->
<xsl:apply-templates select="following-sibling::item
[preceding-sibling::document[1][generate-id() = $id]]"/>
</items>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:variable name="id" select="generate-id()"/>
<xsl:copy>
<xsl:apply-templates select="following-sibling::item_id[1]"/>
<xsl:apply-templates select="following-sibling::item_description[1]"/>
<attributes>
<xsl:apply-templates select="following-sibling::item_attribute_name
[preceding-sibling::item[1][generate-id() = $id]]"/>
</attributes>
</xsl:copy>
</xsl:template>
<xsl:template match="documents">
<xsl:copy>
<xsl:apply-templates select="document"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item_description">
<description>
<xsl:apply-templates/>
</description>
</xsl:template>
<xsl:template match="item_id">
<id>
<xsl:apply-templates/>
</id>
</xsl:template>
<xsl:template match="item_attribute_name">
<attribute>
<name>
<xsl:apply-templates/>
</name>
<xsl:apply-templates select="following-sibling::item_attribute_value[1]"/>
</attribute>
</xsl:template>
<xsl:template match="item_attribute_value">
<value>
<xsl:apply-templates/>
</value>
</xsl:template>
<xsl:template match="item_attribute"/>
</xsl:stylesheet>
<documents>
<document>Review</document>
<document_id>REV#1</document_id>
<item>List of terms</item>
<item_id>10</item_id>
<item_description>Terms used in documents</item_description>
<item_attribute>Term</item_attribute>
<item_attribute_name>SA</item_attribute_name>
<item_attribute_value>Some Attribute</item_attribute_value>
<item_attribute_name>SOA</item_attribute_name>
<item_attribute_value>Some Other Attribute</item_attribute_value>
<document>Interface</document>
<document_id>AC-163</document_id>
<item>List of terms</item>
<item_id>15</item_id>
<item_description>Another item</item_description>
<item_attribute>Term</item_attribute>
<item_attribute_name>Name#1</item_attribute_name>
<item_attribute_value>Att#1</item_attribute_value>
<item_attribute_name>Name#2</item_attribute_name>
<item_attribute_value>Att#2</item_attribute_value>
</documents>
<?xml version="1.0"?>
<documents>
<document>
<document_id>REV#1</document_id>
<items>
<item>
<id>10</id>
<description>Terms used in documents</description>
<attributes>
<attribute>
<name>SA</name>
<value>Some Attribute</value>
</attribute>
<attribute>
<name>SOA</name>
<value>Some Other Attribute</value>
</attribute>
</attributes>
</item>
</items>
</document>
<document>
<document_id>AC-163</document_id>
<items>
<item>
<id>15</id>
<description>Another item</description>
<attributes>
<attribute>
<name>Name#1</name>
<value>Att#1</value>
</attribute>
<attribute>
<name>Name#2</name>
<value>Att#2</value>
</attribute>
</attributes>
</item>
</items>
</document>
</documents>