【问题标题】:Flat XML To Hierarchy XML平面 XML 到层次结构 XML
【发布时间】:2019-08-10 14:43:19
【问题描述】:

我正在研究称为 webmethods(集成工具)的中间件技术,我们有一个问题陈述,需要帮助/指导。

我们得到如下所示的平面 XML,并且需要将 XML 转换为层次结构。 XML 包含ComponentIDrelatedComponentID,如果RelatedCompID 为空或null,那将是我的父母,如果RelatedCompID 不是null,那是我的孩子。

所以基本上它是一个深度递归,它可以包含 n 个父级和 n 个子级。如下图;

ComponentID=0001 is the parent
ComponentID=0002 is the parent
ComponentID=003 is the child of parent 0001

...等等。它可以有任何孩子和任何父母。

现在,我们需要将其转换为层次结构

我们尝试了 webmethods 流语言,但没有成功。我们也尝试用java代码编写,但没有奏效。最后,我们想在无法生成正确逻辑的 XSLT 中尝试

<?xml version="1.0" encoding="UTF-8"?>
<LineItems>
  <LineItem>
    <ComponentID>0001</ComponentID>
    <RelatedCompID></RelatedCompID>
    <Category>MainComponent</Category>         
  </LineItem>
  <LineItem>
    <ComponentID>0002</ComponentID>
    <RelatedCompID></RelatedCompID>
    <Category>MainComponent</Category>         
  </LineItem>
  <LineItem>
    <ComponentID>0003</ComponentID>
    <RelatedCompID></RelatedCompID>
    <Category>MainComponent</Category>         
  </LineItem>
  <LineItem>
    <ComponentID>003</ComponentID>
    <RelatedCompID>0001</RelatedCompID>
    <Category>SubComponent</Category>            
  </LineItem>
  <LineItem>
    <ComponentID>004</ComponentID>
    <RelatedCompID>0001</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>055</ComponentID>
    <RelatedCompID>003</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>066</ComponentID>
    <RelatedCompID>003</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>777</ComponentID>
    <RelatedCompID>055</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>008</ComponentID>
    <RelatedCompID>0002</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>099</ComponentID>
    <RelatedCompID>004</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
  <LineItem>
    <ComponentID>123</ComponentID>
    <RelatedCompID>0002</RelatedCompID>
    <Category>SubComponent</Category>
  </LineItem>
</LineItems>

【问题讨论】:

  • 这是您的输入 XML 还是您的输出 XML?我不知道,但知道这一点很重要...最好指定您输入您想要的输出 XML。
  • 我使用 XSLT 2 作为该版本的问题标签。
  • 嗨马丁,不,不,很好,非常感谢您提供的慷慨帮助:),因为我们使用的工具中的设置很少导致错误:(,但是会解决的。但确实非常感谢您的快速帮助,这将有助于我们进一步取得进步。如果在任何时候,我无法理解,会寻求您的指导。:)

标签: java xml xslt-2.0 webmethods


【解决方案1】:

使用 XSLT,似乎很简单地使用了一个键:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output indent="yes"/>

  <xsl:key name="child" match="LineItem" use="RelatedCompID"/>

  <xsl:template match="/*">
      <Components>
          <xsl:apply-templates select="key('child', '')"/>
      </Components>
  </xsl:template>

  <xsl:template match="LineItem">
      <Component>
          <xsl:copy-of select="* except RelatedCompID"/>
          <SubComponents>
              <xsl:apply-templates select="key('child', ComponentID)"/>
          </SubComponents>
      </Component>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/gWvjQgn

这会将您的输入转换为

<Components>
   <Component>
      <ComponentID>0001</ComponentID>
      <Category>MainComponent</Category>
      <SubComponents>
         <Component>
            <ComponentID>003</ComponentID>
            <Category>SubComponent</Category>
            <SubComponents>
               <Component>
                  <ComponentID>055</ComponentID>
                  <Category>SubComponent</Category>
                  <SubComponents>
                     <Component>
                        <ComponentID>777</ComponentID>
                        <Category>SubComponent</Category>
                        <SubComponents/>
                     </Component>
                  </SubComponents>
               </Component>
               <Component>
                  <ComponentID>066</ComponentID>
                  <Category>SubComponent</Category>
                  <SubComponents/>
               </Component>
            </SubComponents>
         </Component>
         <Component>
            <ComponentID>004</ComponentID>
            <Category>SubComponent</Category>
            <SubComponents>
               <Component>
                  <ComponentID>099</ComponentID>
                  <Category>SubComponent</Category>
                  <SubComponents/>
               </Component>
            </SubComponents>
         </Component>
      </SubComponents>
   </Component>
   <Component>
      <ComponentID>0002</ComponentID>
      <Category>MainComponent</Category>
      <SubComponents>
         <Component>
            <ComponentID>008</ComponentID>
            <Category>SubComponent</Category>
            <SubComponents/>
         </Component>
         <Component>
            <ComponentID>123</ComponentID>
            <Category>SubComponent</Category>
            <SubComponents/>
         </Component>
      </SubComponents>
   </Component>
   <Component>
      <ComponentID>0003</ComponentID>
      <Category>MainComponent</Category>
      <SubComponents/>
   </Component>
</Components>

显然,我必须为嵌套结果中的元素名称(例如Component)和结构(例如SubComponents)做出一些选择,但您应该能够根据您的需求进行调整,而您没有在您的问题。

正如您抱怨由于使用 except 而导致的错误,这是任何 XSLT 2 处理器都应该支持的 XPath 2 运算符,但是使用谓词为 XSLT/XPath 1 重写该表达式很容易*[not(self::RelatedCompID)],所以 XSLT 1 版本是

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output indent="yes"/>

  <xsl:key name="child" match="LineItem" use="RelatedCompID"/>

  <xsl:template match="/*">
      <Components>
          <xsl:apply-templates select="key('child', '')"/>
      </Components>
  </xsl:template>

  <xsl:template match="LineItem">
      <Component>
          <xsl:copy-of select="*[not(self::RelatedCompID)]"/>
          <SubComponents>
              <xsl:apply-templates select="key('child', ComponentID)"/>
          </SubComponents>
      </Component>
  </xsl:template>

</xsl:stylesheet>

在线https://xsltfiddle.liberty-development.net/gWvjQgn/3

关于获得确切 XML 输出结构的帮助,如果您不知道如何调整此答案中的代码示例以产生所需的输出,请编辑您的问题并将其显示为 XML 代码示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2021-09-29
    相关资源
    最近更新 更多