3

XSLT を使用して .net 構成ファイル (web.config/app.config) を解析し、さまざまなアクション (属性の置換や新しい要素の作成など) を実行しようとしましたが、それはうまくいっていますが、今はノード ツリーの一部またはすべてがまだ存在しない場合に備えて、ノード ツリーを再作成しようとしています。残念ながら、私はまだそれを機能させていません。

誰かが私を助けることができるかどうか疑問に思っていましたか?

例 Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="setting1" value="true" />
    <add key="setting2" value="true" />
    <add key="setting3" value="true" />
  </appSettings>
  <system.serviceModel>
    <client>
      <endpoint name="endpointName1" address="http://endpoint1/endpoint1Service.svc" binding="endpointServiceBinding" />
    </client>
  </system.serviceModel>
 </configuration>

他のノードを邪魔せず、存在しないと仮定することなく、新しいノードまたは他のノードを追加できるようにしたいと思います。

クライアント証明書ノード (xpath? は下にあります)

/configuration/system.serviceModel/behaviors/endpointBehaviors
       /behavior[@name=service1BehaviorName]/clientCredentials/clientCertificate

あなたがweb.configを怖がっているなら、彼は問題の単純化されたバージョンです:)

<Node1>
    <Node2>
        <Node3 name="1" value="value1" />
        <Node3 name="2" value="value3" />
    </Node2>
</Node1>

次の手順を実行する方法についての情報が必要です

  1. Node2 が存在しない場合は作成します
  2. 以下のステートメントのいずれか
    • name="3" を持つ新しい Node3 を作成します。
    • name="2" で Node3 の内容を変更します。

新しいノードを追加するコードを書くことはできますが、それらを接続する方法がわかりません

<!-- This should copy everything/be the the base rule -->
<xsl:template name="CopyAll" match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- This will check and see if node2 does not exist, and create it if it does not -->
<xsl:template name="rule_1" match="/Node1">
    <xsl:copy>
        <xsl:if test="not(/Node1/Node2)">
            <Node2>
            <xsl:call-template name="rule_2"/> <!-- call rule 2 to create a node3 -->
            </Node2>
        </xsl:if>
    </xsl:copy>
    <xsl:apply-templates /> <!-- Not sure why this is here, but it seems to need to be here in order to keep copying the xml file-->
</xsl:template>

<!-- Add node3 if it doesn't exist -->
<xsl:template name="rule_2" match="/Node1/Node2/">
    <xsl:if test="not(/Node1/Node2/Node3[@name=1/)>
        <Node3 name="1" value="newValue" />
    </xsl:if>
    <xsl:apply-templates /> <!-- Not sure why this is here, but it seems to need to be here in order to keep copying the xml file-->
 <xsl:template>

 <!-- Change the value of Node3 -->
 <xsl:template match="/Node1/Node2/node3[@name='1']">
<xsl:copy>
     <!-- Blanket statement for keeping all attributes -->
     <xsl:copy-of select ="@*" />
     <!-- Change the below attributes -->
     <xsl:attribute name="value">newValue</xsl:attribute>
     <xsl:apply-templates /><!-- Not sure why this is here, but it seems to need to be here in order to keep copying the xml file-->
</xsl:copy>
 </xsl:template>

編集:別の質問がありましたが、元の質問が解決されたので、最初の回答を質問への回答としてマークしました。Dimitre に公平を期すために、彼のソリューションも同様に機能します。

4

2 に答える 2

4

これは、元の試みよりもややクリーンなアプローチです。XPath では大文字と小文字が区別され、次node3のものと同じではないことに注意してNode3ください。

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

  <xsl:variable name="treeToAddNF">
    <Node2>
      <Node3 name="1" value="">
        <Node4>
          <Node5/>
        </Node4>
      </Node3>
    </Node2>
  </xsl:variable>
  <xsl:variable name="treeToAdd" select="exslt:node-set($treeToAddNF)" />

  <xsl:template match="@*|node()" name="Copy">
    <xsl:param name="contentsToAdd" select="/.." />
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <xsl:apply-templates select="$contentsToAdd" />
    </xsl:copy>
  </xsl:template>

  <!-- Add Node2 to any Node1 that does not have a Node2 -->
  <xsl:template match="Node1[not(Node2)]">
    <xsl:call-template name="Copy">
      <xsl:with-param name="contentsToAdd" select="$treeToAdd/Node2" />
    </xsl:call-template>
  </xsl:template>

  <!-- Add node3 if it doesn't exist -->
  <xsl:template match="Node2[not(Node3/@name = 1)]">
    <xsl:call-template name="Copy">
      <xsl:with-param name="contentsToAdd" select="$treeToAdd/Node2/*" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="Node3[@name = 1][not(Node4)]">
    <xsl:call-template name="Copy">
      <xsl:with-param name="contentsToAdd" select="$treeToAdd/Node2/Node3/*" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="Node3[@name = 1]/Node4[not(Node5)]">
    <xsl:call-template name="Copy">
      <xsl:with-param name="contentsToAdd" select="$treeToAdd/Node2/Node3/Node4/*" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="Node3[@name='1']/@value">
    <xsl:attribute name="value">newValue</xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

この入力で実行すると:

<Node1>

</Node1>

結果は次のとおりです。

<Node1>
  <Node2>
    <Node3 name="1" value="newValue">
      <Node4>
        <Node5 />
      </Node4>
    </Node3>
  </Node2>
</Node1>

この入力で実行すると:

<Node1>
  <Node2>
    <Node3 name="2" value="value3" />
  </Node2>
</Node1>

結果は次のとおりです。

<Node1>
  <Node2>
    <Node3 name="2" value="value3" />
    <Node3 name="1" value="newValue">
      <Node4>
        <Node5 />
      </Node4>
    </Node3>
  </Node2>
</Node1>

そして、この入力で実行すると:

<Node1>
  <Node2>
    <Node3 name="1" value="value1" otherAttribute="7" />
    <Node3 name="2" value="value3" otherAttribute="9"  />
  </Node2>
</Node1>

結果は次のとおりです。

<Node1>
  <Node2>
    <Node3 name="1" value="newValue" otherAttribute="7">
      <Node4>
        <Node5 />
      </Node4>
    </Node3>
    <Node3 name="2" value="value3" otherAttribute="9" />
  </Node2>
</Node1>
于 2013-03-29T19:21:21.313 に答える