2

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

<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>

我应该做的是将其转换为以下实体结构:

文档 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>

我在这项任务中遇到了一些麻烦……请问您有什么帮助吗?这是一些不寻常的“结构化”xml - 你有什么想法吗?

此致!

4

1 回答 1

1

如果您使用 XSLT 2.0,这应该很容易通过XSLT 分组实现,但如果您被 XSLT 1.0 卡住,这里有一个与 XSLT 1.0 兼容的解决方案。

样式表

<?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>
于 2013-02-20T21:10:29.877 回答