2

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

我已经对下面的 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>

4

2 回答 2

2

您是否在 XSLT 中搜索类似“正则表达式”的内容?如果您是,此链接可能对您非常有用:http ://www.w3.org/TR/xslt20/#re​​gular-expressions

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

于 2012-04-04T17:41:55.747 回答
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>
于 2012-04-04T17:56:44.500 回答