0

xpath に基づいて 2 つの xml 間で動的に変換する必要があります。たとえば、次のようなソース xml があります。

<Source>  
 <ZeroLine>
   <FirstLine>
     <Name>Name1</Name>
     <SurName>SurName1</SurName>
   </FirstLine>
   <FirstLine>
     <Name>Name2</Name>
     <SurName>SurName2</SurName>
   </FirstLine>
 </ZeroLine>
 <ZeroLine>
   <FirstLine>
     <Name>Name3</Name>
     <SurName>SurName3</SurName>
   </FirstLine>
   <FirstLine>
     <Name>Name4</Name>
     <SurName>SurName4</SurName>
   </FirstLine>
 </ZeroLine>
</Source>

このソース xml を、異なる構造を持つターゲット xml に変換する必要があります。このターゲット xml 構造は、xPath に基づいて構築されます。

ターゲット xml は、たとえば次のようになります。

<Target>
  <TargetZeroLine>
    <TargetFirstLine>
      <NameIdentifikator>Name1</NameIdentifikator>
      <SurNameIdentifikator>SurName1</SurNameIdentifikator>
    </TargetFirstLine>
    <TargetFirstLine>
      <NameIdentifikator>Name2</NameIdentifikator>
      <SurNameIdentifikator>SurName2</SurNameIdentifikator>
    </TargetFirstLine>
  </TargetZeroLine>
  <TargetZeroLine>
    <TargetFirstLine>
      <NameIdentifikator>Name3</NameIdentifikator>
      <SurNameIdentifikator>SurName3</SurNameIdentifikator>
    </TargetFirstLine>
    <TargetFirstLine>
      <NameIdentifikator>Name4</NameIdentifikator>
      <SurNameIdentifikator>SurName4</SurNameIdentifikator>
    </TargetFirstLine>
  </TargetZeroLine>
</Target>

この例の XPath ルールは次のとおりです。

ソース XPath -> ターゲット XPath

ソース/ZeroLine/FirstLine/Name -> ターゲット/TargetZeroLine/TargetFirstLine/NameIdentifikator

Source/ZeroLine/FirstLine/SurName -> ターゲット/TargetZeroLine/TargetFirstLine/SurNameIdentifikator

ソース xml(xsd) とこれらの xpaths ルールしかなく、ターゲット xml を作成する xslt 変換を動的に構築する必要があります。

この xslt を手動で記述でき、思いどおりに動作しますが、さまざまな xPaths ルールに基づいて動的に構築する必要があります。この例の xslt 変換は次のようになります。

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

<xsl:template match="Source">
    <xsl:element name="Target">         
        <xsl:apply-templates select="ZeroLine"/>            
    </xsl:element>                  
</xsl:template>

<xsl:template match="ZeroLine">
    <xsl:element name="TargetZeroLine"> 
        <xsl:apply-templates select="FirstLine"/>
    </xsl:element>      
</xsl:template>

<xsl:template match="FirstLine">
    <xsl:element name="TargetFirstLine">            
        <xsl:element name="NameIdentifikator">
            <xsl:value-of select="Name"/>
        </xsl:element>                  
        <xsl:element name="SurNameIdentifikator">
            <xsl:value-of select="SurName"/>
        </xsl:element>                  
    </xsl:element>                  
</xsl:template>

</xsl:stylesheet>

そして、私の問題は何ですか?:) 問題は、xPath からターゲットの xslt を構築する方法です。ターゲット xml がどのように見えるかがわかっている場合は、このテンプレートを手動で記述できます。

たとえば、この XPath の xslt テンプレートを手動で作成できます。

Target/TargetZeroLine/TargetFirstLine/NameIdentifikator

それは:

<xsl:template match="FirstLine">
    <xsl:element name="TargetFirstLine">            
        <xsl:element name="NameIdentifikator">
            <xsl:value-of select="Name"/>                 
                    </xsl:element>            
    </xsl:element>                  
</xsl:template>

しかし、この xslt を動的に生成する C# コードをどのように記述すればよいでしょうか? どの xsl:element をどのテンプレートに生成すればよいかわかりません。

または、xPath に基づいて xslt xsl:element を書くことは可能ですか? 私は次のようなことを意味します:

<xsl:template match="FirstLine">
    <xsl:element name="Target/TargetZeroLine/TargetFirstLine">          
        <xsl:element name="NameIdentifikator">

私の質問が理解できるように明確になることを願っています。

更新1

XPath ルールは、ソースとターゲットで異なる場合があります。また、階層のレベルも異なる場合があります。たとえば、次の XPath ルール:

Source/ZeroLine/FirstLine/Name -> Target/NameSection/NameIdentifikator
Source/ZeroLine/FirstLine/SurName -> Target/SurNameSection/SurNameIdentifikator

次の期待される xml を生成する必要があります。

<Target>
<NameSection>
    <NameIdentifikator>Name1</NameIdentifikator>
    <NameIdentifikator>Name2</NameIdentifikator>
    <NameIdentifikator>Name3</NameIdentifikator>
    <NameIdentifikator>Name4</NameIdentifikator>
</NameSection>
<SurNameSection>
    <SurNameIdentifikator>SurName1</SurNameIdentifikator>
    <SurNameIdentifikator>SurName2</SurNameIdentifikator>
    <SurNameIdentifikator>SurName3</SurNameIdentifikator>
    <SurNameIdentifikator>SurName4</SurNameIdentifikator>
</SurNameSection>
</Target>

ありがとう。

4

2 に答える 2

0

XPath を使用して要素名を選択できます。クエリを と重ねるだけ{}です。

<xsl:element name="{Target/TargetZeroLine/TargetFirstLine/NameIdentifikator}">
于 2013-07-15T00:03:31.250 に答える
0

おそらく、ここで物事を過度に複雑にしています。入力 XML と出力 XML だけを見ると、XSLT スタイルシートを記述する 1 つの方法は次のようになります。

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

<xsl:template match="Source">
    <Target>     
        <xsl:apply-templates />            
    </Target>                  
</xsl:template>

<xsl:template match="ZeroLine">
    <TargetZeroLine> 
        <xsl:apply-templates />
    </TargetZeroLine>      
</xsl:template>

<xsl:template match="FirstLine">
    <TargetFirstLine>            
        <xsl:apply-templates />              
    </TargetFirstLine>                  
</xsl:template>

<xsl:template match="Name">
    <NameIdentifikator>            
        <xsl:apply-templates />              
    </NameIdentifikator>                  
</xsl:template>

<xsl:template match="SurName">
    <SurNameIdentifikator>            
        <xsl:apply-templates />              
    </SurNameIdentifikator>                  
</xsl:template>

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

</xsl:stylesheet>

ご覧のとおり、要素の階層構造や位置はあまり気にしません。名前を変更したい個々の要素ごとに単純なテンプレートがあります。

ご覧のとおり、これにより、各テンプレートが同じ構造になります。

<xsl:template match="### INPUT ELEMENT ###">
    <### OUTPUT ELEMENT ###>            
        <xsl:apply-templates />              
    </### OUTPUT ELEMENT ###>                  
</xsl:template>

したがって、XSLT を生成するために C# を本当に書きたい場合は、次のように、プレースホルダーを使用して定数を定義するだけで済みます。

public const string TEMPLATE = @"<xsl:template match="{0}">
    <{1}>            
        <xsl:apply-templates />              
    </{1}>                  
</xsl:template>";

次に、ソース要素名をターゲット要素名にリンクする何らかの方法があると仮定すると、次のようにすることができます

output.WriteLine(string.Format(TEMPLATE, sourceElement, targetElement));
于 2013-07-15T12:17:01.580 に答える