1

我有以下需要转换的 XML:

<?xml version="1.0" encoding="utf-8"?>
<TestRecords>
  <TestData>
    <Users>
      <User>
        <Id>BG123</Id>
        <Name>Bill Gates</Name>
      </User>
      <User>
    <Id>SN123</Id>
    <Name>Satya Nadella</Name>
  </User>
</Users>
<UserDetails>
  <UserDetail>
    <UserId>SN123</UserId>
    <CompanyName>Microsoft Corp</CompanyName>
  </UserDetail>
  <UserDetail>
    <UserId>
      <UserId>BG123</UserId>
      <CompanyName>Bill Gates Foundation</CompanyName>
    </UserId>
  </UserDetail>
</UserDetails>

我需要将此 XML 映射到以下 XML:

<?xml version="1.0" encoding="utf-8"?>
<TestRecords>
  <TestData>
    <Users>
      <User>
        <Id>BG123</Id>
        <Name>Bill Gates</Name>
        <CompanyName>Bill Gates Foundation</CompanyName>
      </User>
      <User>
        <Id>SN123</Id>
        <Name>Satya Nadella</Name>
        <CompanyName>Microsoft Corp</CompanyName>
      </User>
    </Users>
  </TestData>
</TestRecords>

当我遍历用户/用户时,我需要找到 UserDetail/UserId 等于当前用户/Id 的 UserDetail

感谢你并致以真诚的问候

迈克尔

4

2 回答 2

2

如果您不想按照 FCR 的建议执行自定义 XSLT,那么当您有不同的循环结构时,唯一的另一个选择是拥有一个中间模式和两个映射。

UserIn 到 UserInt

哪个生产

<TestRecords>
    <TestData>
        <Users>
            <User>
                <Id>BG123</Id>
                <Name>Bill Gates</Name>
                <UserDetails>
                    <UserID>SN123</UserID>
                    <CompanyName>Microsoft Corp</CompanyName>
                </UserDetails>
                <UserDetails>
                    <UserID>BG123</UserID>
                    <CompanyName>Bill Gates Foundation</CompanyName>
                </UserDetails>
            </User>
            <User>
                <Id>SN123</Id>
                <Name>Satya Nadella</Name>
                <UserDetails>
                    <UserID>SN123</UserID>
                    <CompanyName>Microsoft Corp</CompanyName>
                </UserDetails>
                <UserDetails>
                    <UserID>BG123</UserID>
                    <CompanyName>Bill Gates Foundation</CompanyName>
                </UserDetails>
            </User>
        </Users>
    </TestData>
</TestRecords>

然后,您可以通过第二张地图运行以产生所需的结果。

UserInt 到 UserOut

但是,如果第二个列表很大,这将变得非常低效。

于 2014-05-22T00:20:45.253 回答
0

这是一种常见的查找模式,xslt也有机会用于xsl:key创建可以提高大型文档性能的索引。如果您需要将 a 转换为 xslt ,请参阅此处。.btm

(另外,我假设UserId最后一个UserDetails/UserDetail元素没有双重包装):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

   <xsl:output indent="yes"/>

   <xsl:key name="userLookup" 
            match="/TestRecords/TestData/UserDetails/UserDetail" use="UserId"/>

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

   <!--i.e.match only Users in the first Users/User tree. Actually the explicit
       ancestor qualifier is redundant because of the other suppress template -->
   <xsl:template match="User[ancestor::Users]">
      <User>
         <xsl:copy-of select="child::*" />
         <CompanyName>
            <xsl:value-of select="key('userLookup', Id)/CompanyName"/>
        </CompanyName>
      </User>   
   </xsl:template>

   <!--Suppress the second userdetails part of the tree entirely -->
   <xsl:template match="UserDetails" />
</xsl:stylesheet>

在这里提琴

于 2014-05-22T09:23:33.567 回答