سؤال

We are using a third party XML schema, used to encode a GUI layout in terms of forms and tabs on those forms. This is read in by a third party application over which we have very little control (aka no control). We also get a limited MS JScript interface to handle keypress events, so it would be a fair guess the third party app is also some sort of JScript engine.

We are modifying the GUI layout to add a set of tabs to some forms. The modified xml looks like:

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

Is there any way of referencing the repeated "Our standard tab" to keep it DRY? Something along the lines of the following would be ideal:

<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 We have no control of the reading application, i.e. the solution must leverage standard or Microsoft JScript DOM XML notation as opposed to a different schema.

هل كانت مفيدة؟

المحلول

You could use XSLT:

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

Run against any XML file (<dummy/> would do) will yield the WET version of your XML:

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

Note: There's much more power to be tapped using this approach than the external entities approach. You can further abstract the form definition and actually pull parameters and structures from there rather than use a dummy input XML file. However, the XSLT approach does require another tool that may not already be in your tool chain; external entities will work as-is with compliant XML parsers.

نصائح أخرى

You could use external entities:

Create a file, std-tab.xml:

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

Keep your XML dry by including it where needed:

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

Note: This approach will work without adding any tools to your tool chain; external entities will work as-is with compliant XML parsers. XSLT, on the other hand, requires another tool but affords much more flexible processing options.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top