首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT是否提供了一种通过使用正则表达式来标识xml元素的方法?

XSLT是否提供了一种通过使用正则表达式来标识xml元素的方法?
EN

Stack Overflow用户
提问于 2011-05-20 07:26:27
回答 4查看 473关注 0票数 3

我有一个示例xml文件,如下所示:

代码语言:javascript
复制
--- before transformation ---
<root-node>

   <child-type-A> ... </child-type-A>
   <child-type-A> ... </child-type-A>
   <child-type-B> ... </child-type-B>
   <child-type-C>
      <child-type-B> ... </child-type-B>
      ...
   </child-type-C>


   ...

</root-node>

我想将这个xml文件转换成如下所示:

代码语言:javascript
复制
--- after transformation ---
<root-node>

   <child-node> ... </child-node>
   <child-node> ... </child-node>
   <child-node> ... </child-node>
   <child-node>
      <child-node> ... </child-node>
      ...
   </child-node>

   ...

</root-node>

这实际上意味着文档结构保持不变,但是一些“选择的”元素被重命名。这些选定的元素以相同的前缀开头(在本例中以“子类型-”开头),但有不同的后缀("A“、"B”、“x”、"C“等)。

为什么这么麻烦?我有一个软件需要一个xml文件作为输入。为了方便起见,我使用XML模式轻松地编辑xml文件,该模式有助于确保xml文件是正确的。遗憾的是,当涉及到上下文敏感的方面时,XML模式有点缺乏。这将导致xml文件如/before转换/所示。该软件无法处理这样的xml文件,因为它需要一个文件,如/after转换/中所示。因此,需要进行转型。

我想用XSLT进行转换,并且我已经知道了如何这样做。我的方法是为身份转换定义一个规则,为每个需要重命名的“子类型-*”元素定义一个规则。这个解决方案可以工作,但它没有那么优雅。你最终会有很多规矩。

代码语言:javascript
复制
--- sample transformation rules ---

<!-- Identity transformation -->
<xsl:template match="@*|node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
   </xsl:copy>
</xsl:template>

<xsl:template match="child-type-A">
   <xsl:element name="child-node">
      <xsl:apply-templates select="@*|node()" />
   </xsl:element>
</xsl:template>

...

有办法把它浓缩成两条规则吗?一个用于身份转换,另一个用于所有“子类型-*”元素?也许可以结合使用XSLT和一些正则表达式?还是你必须采取不同的方法来解决这个问题?

EN

回答 4

Stack Overflow用户

发布于 2011-05-20 07:44:27

(修订了我的答覆)

这段代码片段可以很好地处理示例XML。我合并了这两个模板,因为它们都希望对“所有元素”进行操作。我以前的模板没有工作,因为两者匹配相同的选择。

代码语言:javascript
复制
<xsl:template match="@*|node()">
    <xsl:choose>
        <xsl:when test="starts-with(name(), 'child-type')">
            <xsl:element name="child-node">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
           <xsl:copy>
              <xsl:apply-templates select="@*|node()" />
           </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

给定您的源XML:

代码语言:javascript
复制
<root-node>
   <child-type-A> ... </child-type-A>
   <child-type-A> ... </child-type-A>
   <child-type-B> ... </child-type-B>
   <child-type-C>
      <child-type-B> ... </child-type-B>
   </child-type-C>
</root-node>

这将产生以下结果:

代码语言:javascript
复制
<root-node>
<child-node> ... </child-node>
<child-node> ... </child-node>
<child-node> ... </child-node>
<child-node>
    <child-node> ... </child-node>
</child-node>
</root-node>
票数 2
EN

Stack Overflow用户

发布于 2011-05-20 07:35:43

XSLtT有一个一开始-函数,它可以用来识别以'child-type'开头的元素,允许您使用单个模板匹配。见以下相关问题:

选择与开始名匹配的元素。

票数 1
EN

Stack Overflow用户

发布于 2011-05-20 14:06:11

通过将意义附加到元素名称的内部语法(在极端情况下,可以有一个以根元素<Surname_Kay.Firstname_Michael.Country_UK/>的名称捕获所有信息的XML文档)来捕获信息不是一个好主意。但是,如果您有这种形式的数据,当然可以处理它,例如使用表单<xsl:template match="*[matches(name(), 'child-type-[A-Z]')]">的模板规则

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6068764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档