Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不寻常的XSLT转换—XML的结构化_Xml_Xslt_Transformation - Fatal编程技术网

不寻常的XSLT转换—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

我有一些不寻常的问题。我的任务是“结构化XML”。这是一个输入XML(示例):


复习
第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>