2017-02-08 20 views
-1

サンプルXML使用してABCで特定のXMLノードの値を置き換えはXSLT

<MAIN> 
    <A> 
     <first_name>Franklin</first_name> 
     <first_name_Previous>ABCD</first_name_Previous> 
     <formal_name>Franklin Alagala </formal_name> 
     <gender>M</gender> 
     <is_overridden>false</is_overridden> 
    </A> 
    <B> 
     <first_name>Franklin</first_name> 
     <formal_name>Franklin Alagala </formal_name> 
     <gender>M</gender> 
     <gender_Previous>ABCD</gender_Previous> 
     <is_overridden>false</is_overridden> 
    </B> 
</MAIN> 

を以前のよう名前が含まれており、ノードが空であるノードを交換したいです。しかし、ノードに前の名前が含まれていて、値が存在する場合、その名前はそのまま残すべきです。

+3

まさにあなたはこれで立ち往生していますか? –

+0

ようこそスタックオーバーフロー。それは問題を助けてくれる場所なので、たくさんのことを試しても動かないと助けを得ることができます。 「これはどうやってやるの?」と聞く場所ではありません。あなたはそれをするために最善を尽くす必要があります。 http:// stackoverflowを読むことができます。com/help/how-to-ask詳細については – Mikkel

+0

xsltでxmlを読むことができますが、名前の前にあるノードを見つける方法はわかりません。また、私はxslt 1.0のソリューションが必要です –

答えて

0

私は正常に動作しているコードを書かれている:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date"> 
    <xsl:output indent="yes" /> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:if test="contains(name(), '_previous')"> 
     <xsl:if test="not(string(.))">PREVIOUS</xsl:if>  
     </xsl:if> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
0

私はあなたの説明をもう少し別の方法で記述してください。これにより、 が予期される解決策につながりやすくなります。

  1. あなたはMAINABおそらくCDなど)のそれぞれの子要素を見て、のはバケットそれを呼びましょう。

  2. あなたは次のように処理したい各バケット:各その子要素で

    • ルック。
    • この要素に空のテキストコンテンツがない場合は、変更しないでください。
    • は、そうでない場合同じ名前ではなく以前バケツに要素 の内容を読んで(この要素が入力されていません)。
    • 読み込んだ値が空でない場合は、現在の要素のテキストをその値に設定します。
    • それ以外の場合は、現在の要素の内容をABCDに設定します。

次のようにその後、我々は、XSLで上記のルールを記述することができます

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="MAIN/*/*"> 
    <xsl:copy> 
     <xsl:call-template name="proc_node"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template name="proc_node"> 
    <xsl:variable name="thisName" select="name()"/> 
    <xsl:variable name="cnt" select="string-length(.)"/> 
    <xsl:if test="$cnt &gt; 0"> 
     <xsl:value-of select="."/> 
    </xsl:if> 
    <xsl:if test="$cnt = 0"> 
     <xsl:variable name="prevBucket" select="../preceding-sibling::*[1]"/> 
     <xsl:variable name="prevElem" select="$prevBucket/*[name()=$thisName]"/> 
     <xsl:variable name="cnt" select="string-length($prevElem)"/> 
     <xsl:if test="$cnt &gt; 0"> 
     <xsl:value-of select="$prevElem"/> 
     </xsl:if> 
     <xsl:if test="$cnt = 0">ABCD</xsl:if> 
    </xsl:if> 
    </xsl:template> 

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

私は名前の前の持つノードを検索する方法がわかりません。

試してみてください。

*[contains(name(), 'Previous')] 

あなたはさらに空の要素にこれを制限したい場合は、あなたが使用することができます:XMLは大文字と小文字が区別されること

*[contains(name(), 'Previous') and not(node())] 

注意。 「前」は「前」と同じではありません。