1

この質問は、XSLTでの回答の使用から発展しました。特定の属性値を変更して私の状況に対処しましたが、機能しなかったことがわかりました。

これが私のxmlです:

<root>
<Element1 id="VEH1">
    <Element2 />
</Element1>
<Element1 id="VEH2">
    <Element2 />
</Element1>
</root>

これが私のxsl変換です:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="@id">
  <xsl:attribute name="id">
    <xsl:choose>
      <xsl:when test=". = VEH1">
        <xsl:text>VEH01</xsl:text>
      </xsl:when>
      <xsl:when test=". = VEH2">
        <xsl:text>VEH02</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
</xsl:template>
</xsl:stylesheet>

出力を次のようにしたいと思います。

<?xml version="1.0" encoding="UTF-8"?><root>
<Element1 id="VEH01">
    <Element2/>
</Element1>
<Element1 id="VEH02">
    <Element2/>
</Element1>
</root>

しかし、少なくともhttp://xslttest.appspot.com/では、属性値は同じままであり、その理由はわかりません。ありがとう

4

3 に答える 3

2

これを行うにはかなり簡単な方法があります。このテンプレートを使用するだけです。

<xsl:template match="@id[starts-with(.,'VEH')]">
  <xsl:attribute name="id">
    <xsl:value-of select="concat('VEH',format-number(substring(.,4),'00'))" />
  </xsl:attribute>
</xsl:template>

必要に応じて、一致の述語をさらに制限できます。その後に数字以外のものがあるand (floor(substring(.,4)) = substring(.,4))可能性がある場合は追加してください。VEH

于 2012-12-22T21:58:50.960 に答える
2

この単純で短く完全な変換では、明示的な XSLT 条件付き命令は使用されません。

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

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

    <xsl:template match="Element1[starts-with(@id,'VEH')]">
     <Element1 id="VEH0{substring-after(@id,'VEH')}">
      <xsl:apply-templates select="@*[not(name()='id')]|node()"/>
     </Element1>
    </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<root>
    <Element1 id="VEH1">
        <Element2 />
    </Element1>
    <Element1 id="VEH2">
        <Element2 />
    </Element1>
</root>

必要な正しい結果が生成されます。

<root>
   <Element1 id="VEH01">
      <Element2/>
   </Element1>
   <Element1 id="VEH02">
      <Element2/>
   </Element1>
</root>

説明:

  1. アイデンティティ ルールは、実行対象として選択されたすべてのノードを「そのまま」コピーします。

  2. 文字列値が文字列「VEH」で始まるElement1、属性を持つ任意の名前の要素に一致するオーバーライド テンプレートが 1 つあります。id

  3. 要素は、同じ名前とid新しい必要な文字列値を持つ属性を持つリテラル結果要素として再作成されます。AVT (Attribute Value Template) は、コードを短くして読みやすくするために使用されます。

  4. このように作成された要素の本体では、テンプレートはすべての非id属性ノードとすべての子ノードに適用されます。これらは ID テンプレートによって照合され、「そのまま」コピーされます。

更新

@wst は、この数字が 1 桁の場合にのみ、末尾の数字の左側にゼロを埋め込む必要があると提案しました。

この場合に機能するわずかに変更されたソリューションを次に示します。

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

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

    <xsl:template match=
    "Element1[starts-with(@id,'VEH')
            and string-length(@id)=4
            and floor(substring(@id,4)) = floor(substring(@id,4))
             ]">
     <Element1 id="VEH0{substring-after(@id,'VEH')}">
      <xsl:apply-templates select="@*[not(name()='id')]|node()"/>
     </Element1>
    </xsl:template>
</xsl:stylesheet>

この変換がこの XML ドキュメントに適用されると、次のようになります。

<root>
    <Element1 id="VEH1">
        <Element2 />
    </Element1>
    <Element1 id="VEH2">
        <Element2 />
    </Element1>
    <Element1 id="VEH12">
        <Element3 />
    </Element1>
</root>

(新しく追加された要件に関して) 必要な正しい結果が生成されます。

<root>
   <Element1 id="VEH01">
      <Element2/>
   </Element1>
   <Element1 id="VEH02">
      <Element2/>
   </Element1>
   <Element1 id="VEH12">
      <Element3/>
   </Element1>
</root>
于 2012-12-21T04:20:31.187 に答える