在不更改架构的情况下保持 XML DRY

Posted

技术标签:

【中文标题】在不更改架构的情况下保持 XML DRY【英文标题】:Keeping XML DRY without altering the schema 【发布时间】:2013-12-06 02:59:09 【问题描述】:

我们正在使用第三方 XML 模式,用于根据表单和表单上的选项卡对 GUI 布局进行编码。这是由第三方应用程序读取的,我们几乎无法控制(也就是无法控制)。我们还获得了一个有限的 MS JScript 界面来处理按键事件,因此可以公平地猜测第三方应用程序也是某种 JScript 引擎。

我们正在修改 GUI 布局以向某些表单添加一组选项卡。修改后的xml如下:

<forms>
  <form name="form1">
    <tab name="3rd party tab A">
      ...
    </tab>
    <tab name="Our standard tab">
      ...
    </tab>
  </form>
  <form name="form2">
    <tab name="3rd party tab B">
      ...
    </tab>
    <tab name="Our standard tab">
      ...
    </tab>
  </form>
</forms>

是否有任何方法可以引用重复的“我们的标准标签”以使其保持干燥?理想的做法是:

<forms>
  <form name="form1">
    <tab name="3rd party tab A">
      ...
    </tab>
    <tab name="Our standard tab">
      ...
    </tab>
  </form>
  <form name="form2">
    <tab name="3rd party tab B">
      ...
    </tab>
    <?!@reference="/forms/form[@name='form1']/tab[@name='Our standard tab']">
  </form>
</forms>

Nb 我们无法控制阅读应用程序,即解决方案必须利用标准或 Microsoft JScript DOM XML 表示法,而不是使用不同的模式。

【问题讨论】:

【参考方案1】:

你可以使用XSLT:

此 XSLT:

<?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"/>

  <xsl:template match="/">
    <forms>
      <form name="form1">
        <tab name="3rd party tab A">
          ...
        </tab>
        <xsl:call-template name="std-tab"/>
      </form>
      <form name="form2">
        <tab name="3rd party tab B">
          ...
        </tab>
        <xsl:call-template name="std-tab"/>
      </form>
    </forms>
  </xsl:template>

  <xsl:template name="std-tab">
    <tab name="Our standard tab">
      ...
    </tab>
  </xsl:template>

</xsl:stylesheet>

针对任何 XML 文件运行(&lt;dummy/&gt; 会这样做)将产生您的 XML 的 WET 版本:

<?xml version="1.0" encoding="UTF-8"?>
<forms>
   <form name="form1">
      <tab name="3rd party tab A">
          ...
        </tab>
      <tab name="Our standard tab">
      ...
    </tab>
   </form>
   <form name="form2">
      <tab name="3rd party tab B">
          ...
        </tab>
      <tab name="Our standard tab">
      ...
    </tab>
   </form>
</forms>

注意:与外部实体方法相比,使用这种方法可以挖掘更多的权力。您可以进一步抽象表单定义并从那里实际提取参数和结构,而不是使用虚拟输入 XML 文件。但是,XSLT 方法确实需要另一个工具,而您的工具链中可能还没有。外部实体将与兼容的 XML 解析器一起工作。

【讨论】:

本来打算选择另一个答案(另一个更简单),但看起来他们没有使用兼容的解析器:(你说得对,这会更强大!【参考方案2】:

你可以使用external entities:

创建文件,std-tab.xml:

<tab name="Our standard tab">
  ...
</tab>

通过在需要的地方包含 XML 来保持您的 XML 干爽:

<?xml version="1.0" ?>
<!DOCTYPE forms [
<!ENTITY std-tab SYSTEM "std-tab.xml">
]>
<forms>
  <form name="form1">
    <tab name="3rd party tab A">
      ...
    </tab>
    &std-tab;
  </form>
  <form name="form2">
    <tab name="3rd party tab B">
      ...
    </tab>
    &std-tab;
  </form>
</forms>

注意:这种方法无需在您的工具链中添加任何工具即可工作;外部实体将按原样与兼容的 XML 解析器一起工作。另一方面,XSLT 需要其他工具,但提供了更灵活的处理选项。

【讨论】:

以上是关于在不更改架构的情况下保持 XML DRY的主要内容,如果未能解决你的问题,请参考以下文章

在不更改属性顺序的情况下获取 XML

如何在不中断流式传输作业的情况下更改 spark spark 流式事件中的 json 架构?

在不违反 SRP、OCP、DRY 的情况下编写测试

如何在不更改表架构的情况下将查询结果存储在当前表上?

是否可以在不从原始源重新索引的情况下更改 Solr 架构中指定的分析器?

我想在不更改其属性的情况下将 xml 元素“产品”重命名为“项目”,但我不知道该怎么做