使用 xslt 从 xpath 语句列表中注释 xml 实例 [英] Annotating an xml instance from a list of xpath statements with xslt

查看:21
本文介绍了使用 xslt 从 xpath 语句列表中注释 xml 实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个 xpath 语句列表,我想编写一个样式表,它将运行一个 xml 文档并输出相同的文档,但在每个 xpath 语句中标识的节点之前插入一个注释.让我们举一个例子.从一个包含 xpath 语句的 xml 实例开始:

Given a list of xpath statements, I want to write a stylesheet that will run through an xml document and output the same document but with a comment inserted before the node identified in each xpath statement. Let's make up an example. Start with an xml instance holding the xpath statements:

<paths>
  <xpath location="/root/a" annotate="1"/>
  <xpath location="/root/a/b" annotate="2"/>
</paths>

给定输入:

<root>
  <a>
    <b>B</b>
  </a>
  <c>C</c>
</root>

它应该产生:

<root>
  <!-- 1 -->
  <a>
    <!-- 2 -->
    <b>B</b>
  </a>
  <c>C</c>
</root>

我最初的想法是有一个身份样式表,它接受一个 file-list 参数,在其上调用 document 函数以获取 xpath 节点列表.然后它会根据该列表检查输入的每个节点,然后在找到一个注释节点时插入注释节点,但我预计这可能会因为 xpath 列表变大而效率极低(或者可能不会,告诉我.我正在使用撒克逊 9).

My initial thought is to have an identity stylesheet which takes a file-list param, calls the document function on it to get the list of xpath nodes. It would then check each node of the input against that list and then insert the comment node when it finds one, but I expect that might be highly inefficient as the list of xpaths gets large (or maybe not, tell me. I'm using saxon 9).

所以我的问题是:有没有一种有效的方法来做这样的事情?

So my question: Is there an efficient way to do something like this?

推荐答案

概述:

编写一个 meta XSLT 转换,它将 paths 文件作为输入并生成一个新的 XSLT 转换作为输出.这个新的 XSLT 将从您的 root 输入 XML 转换为带注释的副本输出 XML.

Write a meta XSLT transformation that takes the paths file as input and produces a new XSLT transformation as output. This new XSLT will transform from your root input XML to the annotated copy output XML.

注意事项:

  1. 适用于 XSLT 1.0、2.0 或 3.0.
  2. 应该非常有效,特别是如果生成的转换必须在大输入上运行或必须运行重复,因为它有效地编译成原生 XSLT 而不是而不是使用基于 XSLT 的解释器重新实现匹配.
  3. 比必须重建的方法更强大在代码中手动创建元素祖先.因为它将路径映射到template/@match 属性,完整的 @matching可以有效地使用.我已经包含了一个属性值测试一个例子.
  4. 请务必考虑@DanielHaley 提供的优雅 XSLT 2.0 和 3.0 解决方案和@MartinHonnen,特别是如果中间元 XSLT 文件不会为你工作.通过利用 XSLT 3.0 的 XPath 评估设施,@MartinHonnen 的回答似乎能够提供比 template/@match 在这里所做的更强大的匹配.
  1. Works with XSLT 1.0, 2.0, or 3.0.
  2. Should be very efficient, especially if the generated transformation has to be run over a large input or has to be run repeatedly, because it effectively compiles into native XSLT rather than reimplementing matching with an XSLT-based interpreter.
  3. Is more robust than approaches that have to rebuild element ancestry manually in code. Since it maps the paths to template/@match attributes, the full sophistication of @matching is available efficiently. I've included an attribute value test as an example.
  4. Be sure to consider elegant XSLT 2.0 and 3.0 solutions by @DanielHaley and @MartinHonnen, especially if an intermediate meta XSLT file won't work for you. By leveraging XSLT 3.0's XPath evaluation facilities, @MartinHonnen's answer appears to be able to provide even more robust matching than template/@match does here.

此输入 XML 指定 XPaths 和注释:

<paths>
  <xpath location="/root/a" annotate="1"/>
  <xpath location="/root/a/b" annotate="2"/>
  <xpath location="/root/c[@x='123']" annotate="3"/>
</paths>

当输入到这个元 XSLT 转换时:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/paths">
    <xsl:element name="xsl:stylesheet">
      <xsl:attribute name="version">1.0</xsl:attribute>
      <xsl:element name="xsl:output">
        <xsl:attribute name="method">xml</xsl:attribute>
        <xsl:attribute name="indent">yes</xsl:attribute>
      </xsl:element>
      <xsl:call-template name="gen_identity_template"/>
      <xsl:apply-templates select="xpath"/>
    </xsl:element>
  </xsl:template>

  <xsl:template name="gen_identity_template">
    <xsl:element name="xsl:template">
      <xsl:attribute name="match">node()|@*</xsl:attribute>
      <xsl:element name="xsl:copy">
        <xsl:element name="xsl:apply-templates">
          <xsl:attribute name="select">node()|@*</xsl:attribute>
        </xsl:element>
      </xsl:element>
    </xsl:element>
  </xsl:template>

  <xsl:template match="xpath">
    <xsl:element name="xsl:template">
      <xsl:attribute name="match">
        <xsl:value-of select="@location"/>
      </xsl:attribute>
      <xsl:element name="xsl:comment">
        <xsl:value-of select="@annotate"/>
      </xsl:element>
      <xsl:element name="xsl:text">
        <xsl:text disable-output-escaping="yes">&amp;#xa;</xsl:text>
      </xsl:element>
      <xsl:element name="xsl:copy">
        <xsl:element name="xsl:apply-templates">
          <xsl:attribute name="select">node()|@*</xsl:attribute>
        </xsl:element>
      </xsl:element>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

将产生这个 XSLT 转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/root/a">
      <xsl:comment>1</xsl:comment>
      <xsl:text>&#xa;</xsl:text>
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/root/a/b">
      <xsl:comment>2</xsl:comment>
      <xsl:text>&#xa;</xsl:text>
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/root/c[@x='123']">
      <xsl:comment>3</xsl:comment>
      <xsl:text>&#xa;</xsl:text>
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

当提供此输入 XML 文件时:

<root>
  <a>
    <b>B</b>
  </a>
  <c x="123">C</c>
</root>

将生成所需的输出 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <!--1-->
   <a>
    <!--2-->
      <b>B</b>
  </a>
  <!--3-->
   <c x="123">C</c>
</root>

这篇关于使用 xslt 从 xpath 语句列表中注释 xml 实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆