2009-04-06 7 views
1

タイトルが私の問題を明確に説明しているかどうかはわかりませんが、できるだけ詳しく説明します。別のxmlメタデータからxmlを作成するには?

xslt 1を使用してxmlを適切にフォーマットされたものに変換する必要があります。そのため、.net型に逆シリアル化できます。

ソースXML

  <ax21:result type="test.ws.Result"> 
       <ax21:columnNames>fileName</ax21:columnNames> 
       <ax21:columnNames>lockedState</ax21:columnNames> 
       <ax21:columnNames>currentLockOwner</ax21:columnNames> 
       <ax21:columnNames>UUID</ax21:columnNames> 
       <ax21:resultData>Test1.doc</ax21:resultData> 
       <ax21:resultData>true</ax21:resultData> 
       <ax21:resultData>analyst</ax21:resultData> 
       <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
       <ax21:resultData>Test2.doc</ax21:resultData> 
       <ax21:resultData>false</ax21:resultData> 
       <ax21:resultData/> 
       <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
       <ax21:resultData>Test3.doc</ax21:resultData> 
       <ax21:resultData>true</ax21:resultData> 
       <ax21:resultData>analyst</ax21:resultData> 
       <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
       <ax21:resultData>Test4.doc</ax21:resultData> 
       <ax21:resultData>false</ax21:resultData> 
       <ax21:resultData/> 
       <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
      </ax21:result> 

ターゲットXML

<result> 
    <item> 
     <fileName>Test1.doc</fileName> 
     <lockedState>true</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
    <item> 
     <fileName>Test2.doc</fileName> 
     <lockedState>true</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
    <item> 
     <fileName>Test2.doc</fileName> 
     <lockedState>true</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
</result> 

が、これは、XSLTを使用して行うことができますか?はいの場合、plsは私に試してみるためのリンクやサンプルxsltを投稿します。

私は適切かつ確実に成し遂げるために、本当にタフ、不可能ではないことになるだろう、.NET 2.0、C#の、XSLT 1.0

+0

ソースXMLはXML形式のみです。間違いなくXMLの「精神」に準拠していないため、XSLを使用するソリューションはまったくハックされません。あなたがソースフォーマットを支配しているなら、それを何か階層的に変更することを強くお勧めします。 – Welbog

+0

解決策に「ハッキリ」はありません。 XSLTを使用すると、多くの「非伝統的」または一見「解決することが不可能な」問題に対してエレガントなソリューションを提供できます。 –

答えて

3

これは1つのかなり短く、簡単な解決策です:

<ax21:result type="test.ws.Result" 
xmlns:ax21="my:ax21" 
> 
    <ax21:columnNames>fileName</ax21:columnNames> 
    <ax21:columnNames>lockedState</ax21:columnNames> 
    <ax21:columnNames>currentLockOwner</ax21:columnNames> 
    <ax21:columnNames>UUID</ax21:columnNames> 
    <ax21:resultData>Test1.doc</ax21:resultData> 
    <ax21:resultData>true</ax21:resultData> 
    <ax21:resultData>analyst</ax21:resultData> 
    <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
    <ax21:resultData>Test2.doc</ax21:resultData> 
    <ax21:resultData>false</ax21:resultData> 
    <ax21:resultData/> 
    <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
    <ax21:resultData>Test3.doc</ax21:resultData> 
    <ax21:resultData>true</ax21:resultData> 
    <ax21:resultData>analyst</ax21:resultData> 
    <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
    <ax21:resultData>Test4.doc</ax21:resultData> 
    <ax21:resultData>false</ax21:resultData> 
    <ax21:resultData/> 
    <ax21:resultData>f48f0450-9ecc-4a44-b063-898d9d72d112</ax21:resultData> 
</ax21:result> 

たかった:この変換は、次のXML文書に適用され

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

    <xsl:variable name="vCols" select="/*/ax21:columnNames"/> 
    <xsl:variable name="vNumCols" select="count($vCols)"/> 

    <xsl:template match="ax21:result"> 
     <result> 
      <xsl:apply-templates select= 
      "ax21:resultData[position() mod $vNumCols = 1]" 
      /> 
     </result> 
    </xsl:template> 

    <xsl:template match="ax21:resultData"> 
     <item> 
     <xsl:apply-templates mode="create" select= 
     "(.|following-sibling::ax21:resultData) 
           [not(position() > $vNumCols) ] 
     "/> 
     </item> 
    </xsl:template> 

    <xsl:template match="ax21:resultData" mode="create"> 
     <xsl:variable name="vPos" select="position()"/> 
    <xsl:element name="{$vCols[$vPos]}"> 
      <xsl:value-of select="."/> 
      <xsl:if test="not(text())"> 
      <xsl:value-of select= 
      "(.| preceding-sibling::ax21:resultData) 
         [position() mod $vNumCols = $vPos] 
          [text()] 
            [last()] 
      "/> 
      </xsl:if> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

結果は

<result> 
    <item> 
     <fileName>Test1.doc</fileName> 
     <lockedState>true</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
    <item> 
     <fileName>Test2.doc</fileName> 
     <lockedState>false</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
    <item> 
     <fileName>Test3.doc</fileName> 
     <lockedState>true</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
    <item> 
     <fileName>Test4.doc</fileName> 
     <lockedState>false</lockedState> 
     <currentLockOwner>analyst</currentLockOwner> 
     <UUID>f48f0450-9ecc-4a44-b063-898d9d72d112</UUID> 
    </item> 
</result> 

説明:便宜上

  1. 列名とその数は、グローバル変数$vCols$vNumColsに収集されています。

  2. N番目のax21:resultData要素にテンプレートを適用します。ここでは、N mod $vNumCols = 1です。そのような要素はすべて新しいitemを開始します。

  3. すべてax21:resultDataitemの最初の要素は、「no-mode」のテンプレートと一致します。これは単純にラッピングのitem要素を作成し、現在のすべての$ vNumCols ax21:resultData要素に別のテンプレート("create"モード)に適用されます。"create"モードで

  4. テンプレートは、単に名前nは、テンプレートが適用された電流()ノードのposition()ある$vColsのn番目の要素の値である要素を作成します。

  5. 最後に、値が指定されなかった場合は、同じタイプの要素に対して最新の非空の値を(逆順に)取得します。

+0

ありがとうDimitre !!これがXSLTで解決できるかどうかはわかりませんでしたが、私はこの問題についてあなたの意見を得るためにここに投稿しました。再度、感謝します。 –

+0

もう1つの注意点として、私はこれとそのより正確なものを投稿し、Marcが示唆しているようにインデックスを持っているので、XML構造体が変更されました。上記の答えは、新しいテンプレートのテンプレートを作成するのに役立ちます。再度、感謝します。 –

+0

@gk大歓迎です! :)これよりも「厳しい」と思われる多くの問題がありますが、これはXSLTでうまく解決できます。短期間で私はProject Eulerの60の問題を解決しましたが、ペンや鉛筆ではできなかったこれらの問題の解決策がXSLTに実装されました。 –

0

を使用しています。

トラブルがある:多くのノード上のインデックスまたはタイプの兆候は、そのタイプ/位置が何であるかにようありません - あなたは、多かれ少なかれ推測する必要が...

それは別の話だろう少なくとも、追加の属性や、などのようなものがあれば、どういうわけかそれらを一緒に関連付けることができます。

オリジナルのデータを少しでもマッサージできる機会はありますか?それ以外の場合は、C#で読み込んで解析し、必要なものを手に入れるために多くの手動処理を行う必要があるでしょう。

マルク・

+0

全く難しくありません!もちろん、絶対に可能です。 XSLTは、このような問題に洗練されたソリューションを提供する強力な言語です。 1つはちょうど考える必要がある:) –

+0

私は同じ考えを持っていた、私はDimitreの応答を待っていた。とにかく私はもっと意味のある構造でxmlを得るために他のチームと協力してきました。 –

+0

皆さん、本当に挑戦的な問題に対する洗練されたXSLTソリューションを見たい場合は、こちらをご覧ください:http://stackoverflow.com/questions/693596/elegant-examples-of-xslt/693953#693953 –

関連する問題