4

XML を変換する必要があり、いくつかの問題が発生しています...

現在の XML:

<?xml version="1.0" encoding="utf-8"?>
 <Employees>
  <Employee>
   <ManagerFirstName>Joe</ManagerFirstName>
   <ManagerLastName>Schmoe</ManagerLastName>
  </Employee>
 </Employees>

望ましい出力:

<?xml version="1.0" encoding="utf-8"?>
 <Employees>
  <Employee>
   <supervisorName>Schmoe, Joe</supervisorName>
  </Employee>
 </Employees>

現在の XSL:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >
  <xsl:template match="/">
    <xsl:apply-templates select="*"/>
  </xsl:template>
  <xsl:template match="node()">
    <xsl:copy><xsl:apply-templates select="node()"/></xsl:copy>
  </xsl:template>
  <xsl:template match="ManagerFirstName">
        <supervisorName>
        <xsl:apply-templates select="node()"/>
        <xsl:value-of  select="/ManagerLastName"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="/ManagerFirstName"/>
        </supervisorName>
  </xsl:template>
</xsl:stylesheet>

これは機能しておらず、理解できません。現在出力されている XML は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
 <Employees>
  <Employee>
   <supervisorName>Joe, </supervisorName>
   <ManagerLastName>Schmoe/ManagerLastName>
  </Employee>
 </Employees>

すごく近くにいる気がする…

更新 ManagerFirstName と ManagerLastName が空白の場合、その SupervisorName にコンマが含まれていないことを確認するにはどうすればよいですか?

更新 2

<?xml version="1.0" encoding="UTF-8" ?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/> <xsl:strip-space elements="*"/>
 <xsl:template match="/">
   <xsl:apply-templates select="*"/>
 </xsl:template>
 <xsl:template match="@*|node()">
   <xsl:copy>
     <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
 </xsl:template>
 <xsl:template match="Employee">
   <tbl_EmployeeList><xsl:apply-templates select="@*|node()"/></tbl_EmployeeList>
 </xsl:template>
 <xsl:template match="tbl_EmployeeList">
   <xsl:copy>
     <xsl:apply-templates select="@*|node()"/>
       <supervisorName>
         <xsl:value-of select="(ManagerLastName,ManagerFirstName)" separator=", "/>
       </supervisorName>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
4

5 に答える 5

5

XSLT 2.0 を使用しているので、separator属性を使用できますxsl:value-of...

XML 入力

<Employees>
    <Employee>
        <ManagerFirstName>Joe</ManagerFirstName>
        <ManagerLastName>Schmoe</ManagerLastName>
    </Employee>
</Employees>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="Employee">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <supervisorName>
                <xsl:value-of select="(ManagerLastName,ManagerFirstName)" separator=", "/>
            </supervisorName>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XML 出力

<Employees>
   <Employee>
      <supervisorName>Schmoe, Joe</supervisorName>
   </Employee>
</Employees>

注:ManagerLastNameまたはがない場合ManagerFirstName、セパレーターは出力されません。

于 2012-10-24T15:06:07.190 に答える
3

これは次の方法で行うことができます。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Employee">
        <Employee>
            <supervisorName><xsl:value-of select="concat(ManagerLastName, ', ', ManagerFirstName)"/></supervisorName>
        </Employee>
    </xsl:template>
</xsl:stylesheet>
于 2012-10-24T13:37:31.813 に答える
2

これは完全に「プッシュスタイル」のソリューションです:

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

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

 <xsl:template match="Employee">
  <supervisorName><xsl:apply-templates/></supervisorName>
 </xsl:template>

 <xsl:template match="Employee/*">
  <xsl:value-of select="concat(', ', .)"/>
 </xsl:template>
 <xsl:template match="Employee/*[1]"><xsl:apply-templates/></xsl:template>
</xsl:stylesheet>
于 2012-10-24T14:27:00.620 に答える
2

あなたは近くにいます。テンプレートではManagerFirstName、姓を取得するために、わずかに異なる XPath が必要です。

<xsl:template match="ManagerFirstName">
    <supervisorName>
        <xsl:value-of select="../ManagerLastName"/>
        <xsl:text>, </xsl:text>
        <xsl:apply-templates select="node()"/>
    </supervisorName>
</xsl:template>

( のapply-templates値を与えるには で十分です。そのためManagerFirstNameの特定は必要ありませんvalue-of)。次に、姓を個別にコピーするのを停止するための no-op テンプレートが必要です。

<xsl:template match="ManagerLastName" />

また、通常の ID テンプレートは単に一致する@*|node()だけでなく、テンプレートを適用することに注意しnode()てください。属性を使用していないため、例のドキュメントでは違いはありませんが、元の XML に属性がある場合、ID テンプレートのバージョンはそれらをドロップします。

于 2012-10-24T13:39:23.643 に答える
1

すべての応答は良好に見えますが、このアプローチの方がクリーンだと思います(ManagerFirstNameテンプレートをこれに置き換えるだけです)。

<xsl:template match="Employee">
    <supervisorName>
        <xsl:value-of select="concat(ManagerLastName,', ',ManagerFirstName)"/>
    </supervisorName>
</xsl:template>

アップデート:

両方のノードが存在し、空でない場合にのみコンマを表示する場合は、次のように文字列長のifを使用できます。

<xsl:template match="Employee">
    <supervisorName>
        <xsl:value-of select="ManagerLastName"/>
        <xsl:if test="string-length(ManagerLastName) and string-length(ManagerFirstName)">
            <xsl:text> ,</xsl:text>
        </xsl:if>
        <xsl:value-of select="ManagerFirstName"/>
    </supervisorName>
</xsl:template>

更新2: xslt 2.0アプローチに従った、よりクリーンなソリューションですが、空のノードの場合もカバーします。

<xsl:template match="Employee">
    <supervisorName>
        <xsl:value-of select="(ManagerLastName[text()],ManagerFirstName[text()])" separator=", "/>
    </supervisorName>
</xsl:template>
于 2012-10-24T15:39:52.907 に答える