1

一意の子属性をカウントする XPath 式を作成しています。次の xPath 式を使用すると、一意ではないすべての子属性を取得できます。

//*[count(*)=0] 

すべての一意の属性と一意の属性の数を返す XPath 式が必要です

例: XML ファイル

<details>
    <Employee>
        <EmpNo>10</EmpNo>
        <EmpName>TestName</EmpName>
        <Address>
           <Address1>market</Address1>
           <Address2>motel</Address2>
           <Street/>
        </Address>
    </Employee>

    <Employee>
        <EmpNo>20</EmpNo>
        <EmpName>TestName2</EmpName>
        <Address>
           <Address1>school</Address1>
           <Address2>playground</Address2>
           <Street>
                <StreetName>TestStreet2</StreetName>
                <StreetCode>200</StreetCode>
           </Street>
        </Address>
    </Employee>

期待される出力:

  <!-- Unique element's count -->
  <data>6</data>
  <!-- Unique Element Names -->
  <data>EmpNo</data>
  <data>EmpName</data>
  <data>Address1</data>
  <data>Address2</data>
  <data>StreetName</data>
  <data>StreetCode</data>
  <!-- Unique Element values -->
  <!-- Data Set 1 -->
  <data>10</data>
  <data>TestName</data>
  <data>market</data>
  <data>motel</data>
  <data>null</data>
  <data>null</data>
  <!-- Data Set 2 -->
  <data>20</data>
  <data>TestName2</data>
  <data>school</data>
  <data>playground</data>
  <data>TestStreet2</data>
  <data>200</data>

ありがとう。

4

1 に答える 1

1

この XSLT 1.0 スタイルシート

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

  <!-- index data fields by their element name -->
  <xsl:key 
    name  = "kFields" 
    match = "Employee//*"
    use   = "name()" 
  />

  <!-- store a unique list of elements (Muenchian Grouping) -->    
  <xsl:variable name="fields" select="
    /details/Employee//*[
      generate-id()
      =
      generate-id(key('kFields', name())[1])
    ][
      not(
        key('kFields', name())/*
      )
    ]
  " />

  <!-- main output ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template match="/details">
    <xsl:comment> unique element count </xsl:comment>
    <data>
      <xsl:value-of select="count($fields)" />
    </data>
    <xsl:call-template name="newline" />

    <xsl:comment> unique element names </xsl:comment>
    <xsl:for-each select="$fields">
      <data>
        <xsl:value-of select="name()" />
      </data>
      <xsl:call-template name="newline" />
    </xsl:for-each>

    <xsl:comment> unique element values </xsl:comment>
    <xsl:apply-templates select="Employee" />
  </xsl:template>

  <!-- Employee output ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template match="Employee">
    <xsl:variable name="this" select="." />

    <xsl:comment> data set <xsl:value-of select="position()" /> </xsl:comment>
    <xsl:for-each select="$fields">
      <xsl:variable 
        name="val" 
        select="$this//*[not(*) and name() = name(current())]" 
      />
      <data>
        <xsl:choose>
          <xsl:when test="normalize-space($val) != ''">
            <xsl:value-of select="$val" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>null</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </data>
      <xsl:call-template name="newline" />
    </xsl:for-each>
  </xsl:template>

  <!-- Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
  <xsl:template name="newline">
    <xsl:value-of select="'&#xA;'" />
  </xsl:template>

</xsl:stylesheet>

生成されます(改行は異なる方法で再現される場合があります):

<!-- unique element count -->
<data>6</data>

<!-- unique element names -->
<data>EmpNo</data>
<data>EmpName</data>
<data>Address1</data>
<data>Address2</data>
<data>StreetName</data>
<data>StreetCode</data>

<!-- unique element values -->

<!-- data set 1 -->
<data>10</data>
<data>TestName</data>
<data>market</data>
<data>motel</data>
<data>null</data>
<data>null</data>

<!-- data set 2 -->
<data>20</data>
<data>TestName2</data>
<data>school</data>
<data>playground</data>
<data>TestStreet2</data>
<data>200</data>

ノート:

  • //*[count(*)=0]//*[not(*)]等しいです。後者の方がいいです。
  • <xsl:key>Muenchian Groupingを使用して、 の子孫の中で一意の要素名を見つけました。<Employee>
  • 変数 の XPath 式は、次の$fields2 つのこと を行います。
    • 最初に、要素の Muenchian グループ化を使用して、要素を一意にしname()ます。
    • 次に、残りの要素をチェックします。同じ名前の要素は、入力のどこにでも子を持つことはできません ( not( key('kFields', name())/* )。そうでない場合<data>Street</data>、出力に表示されます。
  • 出力形式があいまいです。名前が同じで入れ子の位置が異なる要素があると、めちゃくちゃになります。
于 2012-07-16T11:42:18.733 に答える