1

これは私の入力xmlです。xml には、最大 3 つのノードと最小 1 つのノードを含めることができます。以下のように、入力 xml が持つことができる最小ノード

<Root>
   <node>uniquename</node>
</Root>

入力 xml が持つことができる最大ノードは次のとおりです。Uniquename を含むノードは常に存在します。

以下のサンプルの望ましい出力のための私のサンプル入力xml

<Root>
   <node>abc</node>
   <node>e1</node>
   <node>uniquename2</node>
</Root>

値「abc」は、すべての入力 xml に共通です。値 e1 は、バージョン番号のようなものです。e1 から e9 までを持つことができます。また、e1.1 から e9.9 のようなマイナー バージョンを持つこともできます。3 番目のノードは一意です。私の出力は以下のテキストである必要があり、以下のサンプルは目的の出力として

Unique name with version from the xml - uniquename2e1
version number - e1
common name - Present in the input

入力 xml ノードの順序はさまざまです。つまり、バージョン番号が一番上にくる場合もあれば、一意の名前が一番上にくる場合もあります。通称も同様です。それにもかかわらず、私の出力にはuniquenameの後にバージョン番号が続くはずです。入力 xml に共通名がない場合、出力テキストはそれが存在しないことを示す必要があります。

バージョン番号が入力にない場合、バージョン番号の行は出力から空白になる可能性があります

Unique name with version from the xml - uniquename3
common name - Present/Absent in the input.

私は xslt 2.0 プロセッサを持っていませんが、私の xslt プロセッサは xmlns:regexp="http://exslt.org/regular-expressions" をサポートしています。バージョン管理部分を見つけるためにこれを使用することを考えていました。

編集

一意の名前は、バージョン番号のパターンに従ってい^e\d(\.\d)*$ないか、一般的な名前ではありません

4

2 に答える 2

1

この XSLT 1.0 変換:

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:my="my:my">
     <xsl:output method="text"/>

     <my:commonAbsent/>

     <xsl:variable name="vVer" select=
      "/*/node
           [starts-with(., 'e')
          and
           number(substring(.,2)) = number(substring(.,2))]"/>

     <xsl:template match="/*">
      <xsl:apply-templates mode="unique" select=
       "node[not(. = 'abc'
                or
                 generate-id() =generate-id($vVer)
                 )
             ]"/>
      <xsl:apply-templates select="$vVer" mode="ver"/>

      <xsl:apply-templates select=
       "node[. = 'abc']
       |
        document('')
           [not(current()/node[.='abc'])]
                        /*/my:commonAbsent
       "/>
     </xsl:template>

     <xsl:template match="node" mode="unique">
     Unique name with version from the xml - <xsl:text/>

     <xsl:value-of select="concat(., $vVer)"/>
     </xsl:template>

     <xsl:template match="node" mode="ver">
     Version number - <xsl:value-of select="$vVer"/>
     </xsl:template>

     <xsl:template match="node[. = 'abc']">
     Common name - Present in the input
     </xsl:template>

     <xsl:template match="my:commonAbsent">
     Common name - Absent in the input
     </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<Root>
    <node>abc</node>
    <node>e1</node>
    <node>uniquename2</node>
</Root>

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

 Unique name with version from the xml - uniquename2e1
 Version number - e1
 Common name - Present in the input

「共通名」を持たない XML ドキュメントに同じ変換を適用すると、次のようになります。

<Root>
    <node>e1</node>
    <node>uniquename2</node>
</Root>

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

 Unique name with version from the xml - uniquename2e1
 Version number - e1
 Common name - Absent in the input

最後に、「バージョン」が XML ドキュメントで表されていない場合:

<Root>
    <node>abc</node>
    <node>uniquename2</node>
</Root>

同じ変換を再度適用すると、必要な正しい結果が得られます。

 Unique name with version from the xml - uniquename2
 Common name - Present in the input

説明:

結果ツリー内のノード (この場合はすべてテキスト ノード) の順序は、xsl:apply-templatesこれらの結果ツリー ノードを生成するテンプレートを実行するために選択する命令の順序によって完全に決定されます。

于 2012-06-22T04:29:14.510 に答える
0

EXSLT にアクセスできないため、これをテストしていませんが、このスタイル シートは機能するはずです。また、このスクリプトには、ノードを変数に入れないようにして改善の余地がたくさんあります。 not( 条件) で xsl:if および xsl:if の代わりに xsl:choose を使用して繰り返し計算する必要があります。したがって、これを簡単で汚いバージョンと考えてください。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:regexp="http://exslt.org/regular-expressions"
  extension-element-prefixes="regexp">
<xsl:import href="regexp.xsl" />    
<xsl:output method="text" />

<xsl:template match="/">
<xsl:value-of select="Root/node[.!='abc'][regexp:test(.,'^e\d(\.\d)*$','')]" /><xsl:value-of select="Root/node[regexp:test(.,'^e\d(\.\d)*$','')]" /> 
<xsl:if test="Root/node[regexp:test(.,'^e\d(\.\d)*$','')]">
version number - <xsl:value-of select="Root/node[regexp:test(.,'^e\d(\.\d)*$','')]" />
</xsl:if>  
<xsl:if test="Root/node[.='abc']">
common name - Present in the input
</xsl:if>  
<xsl:if test="not( Root/node[.='abc'])">
common name - Absent in the input
</xsl:if>  
</xsl:template>

</xsl:stylesheet>
于 2012-06-22T04:28:48.467 に答える