XSLT 2.0测试以特定值开头的元素名称

时间:2012-04-04 17:37:16

标签: xml xslt xslt-2.0

我做了一些环顾四周,但我没有看到明显的问题答案。我确定我忽略了什么,但我不知道是什么。

我已经对下面的XML做了一些预处理来编辑一些元素名称,并且在预处理之后我有一个XSL样式表来执行简单的身份转换。但是,我想知道是否有办法避免预处理步骤并在一个样式表中完成所有内容。两个XML输入之间的主要区别是<subj*>已成为<subj>

是否有一种方法可以测试元素名称的起始(或者也就是说,我猜)值?非常感谢你的时间和建议。

我有XML输入,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <row>
      <issueNumber>1.001</issueNumber>
      <subj1>Cats</subj1>
      <subj2>LOLCats</subj2>
      <subj3>Cheezburgers</subj3>
      <subj4></subj4>
   </row>
   <row>
      <issueNumber>2.001</issueNumber>
      <subj1>Cats</subj1>
      <subj2>LOLCats</subj2>
      <subj3>NOMS</subj3>
      <subj4>Cheezburger</subj4>
   </row>
   <row>
      <issueNumber>3.001</issueNumber>
      <subj1>NOMS</subj1>
      <subj2></subj2>
      <subj3></subj3>
      <subj4></subj4>
   </row>
</root>

我正在使用以下XSL处理它:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="row">
    <!--<xsl:result-document href="{concat(issueNumber, '.xml')}">-->
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    <!--</xsl:result-document>-->    
</xsl:template>

<xsl:template match="issueNumber">
    <xsl:copy>
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

<xsl:template match="subj">
    <xsl:choose>
        <xsl:when test="not(string(.))"></xsl:when>
        <xsl:when test="string(.)">
            <subject>
                <xsl:apply-templates />
            </subject>
        </xsl:when>
    </xsl:choose>
</xsl:template>

2 个答案:

答案 0 :(得分:2)

您是否在XSLT中搜索“regex”之类的内容?如果您愿意,此链接可能对您非常有用:http://www.w3.org/TR/xslt20/#regular-expressions

但是,此解决方案仅适用于XSLT 2.0。您可能会失去与旧版XSLT版本的兼容性。

答案 1 :(得分:1)

如果我正确理解了这个问题,你可以这样做:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="*[starts-with(name(),'subj')]">
    <subj>
      <xsl:if test="string(.)">
        <subject>
          <xsl:apply-templates/>
        </subject>
      </xsl:if>
    </subj>
  </xsl:template>

</xsl:stylesheet>

使用您的XML输入(更正为格式良好):

<root>
  <row>
    <issueNumber>1.001</issueNumber>
    <subj1>Cats</subj1>
    <subj2>LOLCats</subj2>
    <subj3>Cheezburgers</subj3>
    <subj4></subj4>
  </row>
  <row>
    <issueNumber>2.001</issueNumber>
    <subj1>Cats</subj1>
    <subj2>LOLCats</subj2>
    <subj3>NOMS</subj3>
    <subj4>Cheezburger</subj4>
  </row>
  <row>
    <issueNumber>3.001</issueNumber>
    <subj1>NOMS</subj1>
    <subj2></subj2>
    <subj3></subj3>
    <subj4></subj4>
  </row>
</root>

产生以下输出:

<root>
   <row>
      <issueNumber>1.001</issueNumber>
      <subj>
         <subject>Cats</subject>
      </subj>
      <subj>
         <subject>LOLCats</subject>
      </subj>
      <subj>
         <subject>Cheezburgers</subject>
      </subj>
      <subj/>
   </row>
   <row>
      <issueNumber>2.001</issueNumber>
      <subj>
         <subject>Cats</subject>
      </subj>
      <subj>
         <subject>LOLCats</subject>
      </subj>
      <subj>
         <subject>NOMS</subject>
      </subj>
      <subj>
         <subject>Cheezburger</subject>
      </subj>
   </row>
   <row>
      <issueNumber>3.001</issueNumber>
      <subj>
         <subject>NOMS</subject>
      </subj>
      <subj/>
      <subj/>
      <subj/>
   </row>
</root>