如何在 WORD 文档中嵌入格式化的 XML 源?

如何在 WORD 文档中嵌入格式化的 XML 源?

我正在用 WORD 编写一个文档,其中包含 XML 源代码(整个文件)作为示例。我嵌入当前 XML 的方式相当麻烦,而且在我看来不太容易维护:

  • 我正在 WORD 中完成文档的编辑,并使用 Acrobat 从中创建 PDF
  • 接下来,我用 IE 打开我的 XML 文件(2 个输入文件,2 个生成的输出文件),然后用 Acrobat 提供的 PDF 打印机打印它们
  • 现在,我打开 Acrobat Pro 并将四个 XML-PDF 文件附加到我的原始文档中

对我来说,该工作流程的问题在于,为了完成文档工作需要太多的体力劳动。

我到目前为止尝试过的方法并没有让我真正满意:

  • 将每个 XML 转换为 PDF,并按上述方法附加它们
  • 使用以下方式打开 XML 文件南加州大学,复制为 RTF 并粘贴到 Word 中
  • 尝试使用 LaTeX 软件包 minted、pygments 和 listings(我也可以用 LaTeX 编写文档),但发现了一些无法解决的问题在每个包中

我正在寻找一种生成文档的方法更加自动化。例如嵌入包含 IE 格式的 XML 文件(我发现它非常易读)。应通过引用包含这些文件,这样我就不必在每次 XML 更改时手动粘贴 XML 源。


编辑:
使用优秀的回答给出杰里米,我终于能够设置一个 XSLT,将给定的 XML 文件转换为漂亮的 HTML。我的 XSLT 基于原始 IE 样式表,但略有修改,因为 Word 拒绝执行 IE 样式表中所需的动态内容。

针对这一点,我修改了 IE XSLT(找到这里) 这样就不再需要脚本了(在我的情况下绝对不需要)。文档:这是样式表:

<?xml version="1.0"?>
<!--
  IE5 default style sheet, provides a view of any XML document
  and provides the following features:
  - color coding of markup
  - color coding of recognized namespaces - xml, xmlns, xsl, dt

  This style sheet is available in IE5 in a compact form at the URL
  "res://msxml.dll/DEFAULTSS.xsl".  This version differs only in the
  addition of comments and whitespace for readability.

  Author:  Jonathan Marsh ()
  Modified:   05/21/2001 by Nate Austin ()
                         Converted to use XSLT rather than WD-xsl
-->

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dt="urn:schemas-microsoft-com:datatypes" xmlns:d2="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
  <xsl:strip-space elements="*"/>
  <xsl:output method="html"/>
  <xsl:template match="/">
    <HTML>
      <HEAD>
        <STYLE>
          BODY {font:x-small 'Courier New'; margin-right:1.5em}
          <!-- tag -->
          .t  {color:#990000}
          <!-- attribute names -->
          .an {color:#990000;}
          <!-- tag in xsl namespace -->
          .xt {color:#990099}
          <!-- attribute in xml or xmlns namespace -->
          .ns {color:red}
          <!-- attribute in dt namespace -->
          .dt {color:green}
          <!-- markup characters -->
          .m  {color:blue}
          <!-- text node -->
          .tx {font-weight:bold}
          <!-- single-line (inline) cdata -->
          .di {}
          <!-- DOCTYPE declaration -->
          .d  {color:blue}
          <!-- pi -->
          .pi {color:blue}
          <!-- single-line (inline) comment -->
          .ci {color:#888888}
        </STYLE>
      </HEAD>
      <BODY class="st">
        <xsl:apply-templates>
          <xsl:with-param name="depth">0</xsl:with-param>
        </xsl:apply-templates>
      </BODY>
    </HTML>
  </xsl:template>

  <!-- decides whether we have a tag in an xsl namespace or a regular tag -->
  <xsl:template name="classwriter">
    <xsl:param name="curname"/>
    <SPAN>
      <xsl:attribute name="class"><xsl:if test="starts-with($curname,'xsl:')">x</xsl:if>t</xsl:attribute>
      <xsl:value-of select="$curname"/>
    </SPAN>
  </xsl:template>

  <!-- Helper that does the indent -->
  <xsl:template name="indent">
    <xsl:param name="depth"/>
    <xsl:if test="$depth &gt; 0">
      <xsl:text>&#160;&#160;</xsl:text>
      <xsl:call-template name="indent">
        <xsl:with-param name="depth" select="$depth - 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <!-- Template for pis not handled elsewhere -->
  <xsl:template match="processing-instruction()">
    <DIV class="e">
      <SPAN class="m">&lt;?</SPAN>
      <SPAN class="pi">
        <xsl:value-of select="name()"/>&#160;<xsl:value-of select="."/>
      </SPAN>
      <SPAN class="m">?&gt;</SPAN>
    </DIV>
  </xsl:template>

  <!-- Template for attributes not handled elsewhere -->
  <xsl:template match="@*">
    <SPAN class="an">&#160;<xsl:value-of select="name()"/></SPAN><SPAN class="m">="</SPAN><B><xsl:value-of select="."/></B><SPAN class="m">"</SPAN>
  </xsl:template>

  <!-- Template for text nodes -->
  <xsl:template match="text()">
    <DIV class="e">
      <SPAN class="tx">
        <xsl:value-of select="."/>
      </SPAN>
    </DIV>
  </xsl:template>


  <!-- Note that in the following templates for comments
and cdata, by default we apply a style appropriate for
single line content (e.g. non-expandable, single line
display).  But we also inject the attribute 'id="clean"' and
a script call 'f(clean)'.  As the output is read by the
browser, it executes the function immediately.  The function
checks to see if the comment or cdata has multi-line data,
in which case it changes the style to a expandable,
multi-line display.  Performing this switch in the DHTML
instead of from script in the XSL increases the performance
of the style sheet, especially in the browser's asynchronous
case -->

  <!-- Template for comment nodes -->
  <xsl:template match="comment()">
    <xsl:param name="depth"/>
    <DIV class="k">
      <SPAN>
        <SPAN class="m">
          <xsl:call-template name="indent">
            <xsl:with-param name="depth" select="$depth"/>
          </xsl:call-template>
          &lt;!--
        </SPAN>
      </SPAN>
      <SPAN class="ci">
        <xsl:value-of select="."/>
      </SPAN>
      <SPAN class="m">--&gt;</SPAN>
    </DIV>
  </xsl:template>

  <!-- Note the following templates for elements may
examine children.  This harms to some extent the ability to
process a document asynchronously - we can't process an
element until we have read and examined at least some of its
children.  Specifically, the first element child must be
read before any template can be chosen.  And any element
that does not have element children must be read completely
before the correct template can be chosen. This seems an
acceptable performance loss in the light of the formatting
possibilities available when examining children. -->

  <!-- Template for elements not handled elsewhere (leaf nodes) -->
  <xsl:template match="*">
    <xsl:param name="depth"/>
    <DIV class="e">
      <xsl:call-template name="indent">
        <xsl:with-param name="depth" select="$depth"/>
      </xsl:call-template>
      <SPAN class="m">&lt;</SPAN>
      <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
      <xsl:apply-templates select="@*"/>
      <SPAN class="m"> /&gt;</SPAN>
    </DIV>
  </xsl:template>

  <!-- Template for elements with comment, pi and/or cdata children -->
  <xsl:template match="*[comment() | processing-instruction()]">
    <xsl:param name="depth"/>
    <DIV class="e">
      <SPAN class="m">&lt;</SPAN>
      <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
      <xsl:apply-templates select="@*">
        <xsl:with-param name="depth" select="$depth + 1"/>
      </xsl:apply-templates>
      <SPAN class="m">&gt;</SPAN>
      <DIV>
        <xsl:apply-templates>
          <xsl:with-param name="depth" select="$depth + 1"/>
        </xsl:apply-templates>
        <DIV>
          <SPAN class="m">&lt;/</SPAN>
          <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
          <SPAN class="m">&gt;</SPAN>
        </DIV>
      </DIV>
    </DIV>
  </xsl:template>

  <!-- Template for elements with only text children -->
  <xsl:template match="*[text() and not(comment() | processing-instruction())]">
    <xsl:param name="depth"/>
    <DIV class="e">
      <!-- write the starting tag -->
      <xsl:call-template name="indent">
        <xsl:with-param name="depth" select="$depth"/>
      </xsl:call-template>
      <SPAN class="m">&lt;</SPAN>
      <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
      <xsl:apply-templates select="@*">
        <xsl:with-param name="depth" select="$depth + 1"/>
      </xsl:apply-templates>
      <SPAN class="m">&gt;</SPAN>
      <!-- write the tag content -->
      <SPAN class="tx">
        <xsl:value-of select="."/>
      </SPAN>
      <!-- write the end tag -->
      <SPAN class="m">&lt;/</SPAN>
      <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
      <SPAN class="m">&gt;</SPAN>
    </DIV>
  </xsl:template>

  <!-- Template for elements with element children -->
  <xsl:template match="*[*]">
    <xsl:param name="depth"/>
    <DIV class="e">
      <xsl:call-template name="indent">
        <xsl:with-param name="depth" select="$depth"/>
      </xsl:call-template>
      <SPAN class="m">&lt;</SPAN>
      <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
      <xsl:apply-templates select="@*" />
      <SPAN class="m">&gt;</SPAN>
      <DIV>
        <xsl:apply-templates>
          <xsl:with-param name="depth" select="$depth + 1"/>
        </xsl:apply-templates>
        <DIV>
          <xsl:call-template name="indent">
            <xsl:with-param name="depth" select="$depth"/>
          </xsl:call-template>
          <SPAN class="m">&lt;/</SPAN>
          <xsl:call-template name="classwriter"><xsl:with-param name="curname" select="name()"/></xsl:call-template>
          <SPAN class="m">&gt;</SPAN>
        </DIV>
      </DIV>
    </DIV>
  </xsl:template>

  <xsl:template match="text()" />
</xsl:stylesheet>

答案1

您可以通过以下方式进行在 Word 文档中插入 INCLUDETEXT 字段


  • 获取或创建输出有效 WordPressingML(Word 2003、2007)的 XSL 转换。我在这里找到了一个看起来可能被 IE 使用的转换C:\Windows\SysWOW64\wbem\en-US\xml.xsl

  • 插入 INCLUDETEXT 字段,如下所示:

    { INCLUDETEXT "c:\\a\\myxml.xml" \t c:\\a\\myxml.xsl \c xml }

当您的源 XML 文件发生变化时,您将需要更新每个 INCLUDETEXT 字段(突出显示它并按F3)或添加一些 VBA 以在加载文档时刷新字段。

相关内容