0

1 つの XML 要求を (XML に) 変更してから、さらに送信する必要があります。XSLT についての予備知識はありません。私が持っていると言う

<Combined>
<Profile>
  <Fullname>John Doe</Fullname>
  <OtherData>
    <Birthdate>1996</Birthdate>
    <FavoriteBooks>
      <Book>
        <id>1</id>
        <description>Libre1</description>
      </Book>
      <Book>
        <id>2</id>
        <description>Libre2</description>
      </Book>
      <Book>
        <id>3</id>
        <description></description>
      </Book>
      <Book>
        <id>4</id>
        <description>Libre4</description>
      </Book>
    </FavoriteBooks>
  </OtherData>
</Profile>
<LoadedData>
  <NewBirthdate>1998</NewBirthdate>
  <BooksUpdate>
    <Book id="1">
      <BookText>Book1</BookText>
    </Book>
    <Book id="2">
      <BookText>Book2</BookText>
    </Book>
    <Book id="3">
      <BookText>Book3</BookText>
    </Book>
    <Book id="4">
      <BookText>Book4</BookText>
    </Book>
    <Book id="5">
      <BookText>Book5</BookText>
    </Book>
  </BooksUpdate>
</LoadedData>

そして手に入れたい

<Profile>
<Fullname>John Doe</Fullname>
<OtherData>
  <Birthdate>1998</Birthdate>
  <FavoriteBooks>
    <Book>
      <id>1</id>
      <description>Libre1Book1</description>
    </Book>
    <Book>
      <id>2</id>
      <description>Libre2Book2</description>
    </Book>
    <Book>
      <id>3</id>
      <description>empty</description>
    </Book>
    <Book>
      <id>4</id>
      <description>Libre4Book4</description>
    </Book>
    <Book>
      <id>5</id>
      <description>new Book5</description>
    </Book>
  </FavoriteBooks>
</OtherData>

私はかなり哀れな試みをしましたが、明らかにうまくいきません。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
  <Profile>
    <xsl:apply-templates select="Combined/Profile/Fullname" />
  </Profile>
  <Otherdata>
    <Birthdate>
      <xsl:apply-templates select="Combined/LoadedData/NewBirthdate"/>
    </Birthdate>
    <FavoriteBooks>
      <xsl:for-each select="/Combined/Profile/OtherData/FavoriteBooks/Book">
        <Book>
          <id>
            <xsl:value-of select="id"/>
          </id>
          <description>
            <xsl:value-of select="description"/>
            <xsl:apply-templates select="/Combined/LoadedData/BooksUpdate/Book[@id='']" />
          </description>
        </Book>
      </xsl:for-each>
    </FavoriteBooks>
  </Otherdata>
</xsl:template>
</xsl:stylesheet>

なりたい自分に近づくにはどうしたらいいの?w3schoolsのチュートリアルは役に立たないので、ジャンプスタートするための本を教えてください:(

4

1 に答える 1

1

どうですか?

あなたが説明したロジックによれば、説明は「空」ではなく「Book3」(「Book3」と結合された空の文字列)になります。

<!-- root and static content -->
<xsl:template match="/">
    <xsl:apply-templates select='Combined/Profile' />
</xsl:template>

<!-- identity/copy, with some tweaks -->
<xsl:template match='node()|@*'>

    <!-- copy node -->
    <xsl:copy>

        <!-- add in its attributes -->
        <xsl:apply-templates select='@*' />

        <!-- now either apply same treatment to child nodes, or something special -->
        <xsl:choose>

            <!-- use updated birthdate -->
            <xsl:when test='name() = "Birthdate"'>
                <xsl:value-of select='/Combined/LoadedData/NewBirthdate' />
            </xsl:when>

            <!-- merge book descriptions -->
            <xsl:when test='name() = "description"'>
                <xsl:value-of select='concat(., /Combined/LoadedData/BooksUpdate/Book[@id = current()/../id]/BookText)' />
            </xsl:when>

            <!-- or just keep recursing -->
            <xsl:otherwise>
                <xsl:apply-templates select='node()' />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>

    <!-- if we've done all books, add in any in the loaded data but not the original data -->
    <xsl:if test='name() = "Book" and not(count(following-sibling::Book))'>
        <xsl:variable name='orig_book_ids'>
            <xsl:for-each select='../Book'>
                <xsl:value-of select='concat("-",id,"-")' />
            </xsl:for-each>
        </xsl:variable>
        <xsl:apply-templates select='/Combined/LoadedData/BooksUpdate/Book[not(contains($orig_book_ids, concat("-",@id,"-")))]' mode='new_books' />
    </xsl:if>
</xsl:template>

<!-- new books -->
<xsl:template match='Book' mode='new_books'>
    <Book>
        <id><xsl:value-of select='@id' /></id>
        <description>new <xsl:value-of select='BookText' /></description>
    </Book>
</xsl:template>

この XMLPlayground セッションで実行できます(出力ソースを参照)。

于 2012-06-28T09:54:46.033 に答える