Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSLT&;XPath非常复杂的数据转换_Xml_Xslt_Serialization_Xpath - Fatal编程技术网

Xml XSLT&;XPath非常复杂的数据转换

Xml XSLT&;XPath非常复杂的数据转换,xml,xslt,serialization,xpath,Xml,Xslt,Serialization,Xpath,我正在研究以各种XML格式传递数据的方法,虽然我能够理解如何解析数据的大部分内容,但我对XSLT和XPath的了解还不够,不知道从哪里开始组合这种类型的多重转换,其中一些数据显然只是查找,一些数据是重复的,元素必须重命名,一些数据在属性中,一些在值中,模板可能必须按特定顺序处理或使用变量调用。我不认为这里有这种类型的例子,如果我们能得到一个,它可能会为人们解决很多问题 我们的目标是从多个以不同形式提供相似数据的源获取输入,将它们转换为通用XML格式,并只编写一(1)条progam处理路径,而不是

我正在研究以各种XML格式传递数据的方法,虽然我能够理解如何解析数据的大部分内容,但我对XSLT和XPath的了解还不够,不知道从哪里开始组合这种类型的多重转换,其中一些数据显然只是查找,一些数据是重复的,元素必须重命名,一些数据在属性中,一些在值中,模板可能必须按特定顺序处理或使用变量调用。我不认为这里有这种类型的例子,如果我们能得到一个,它可能会为人们解决很多问题

我们的目标是从多个以不同形式提供相似数据的源获取输入,将它们转换为通用XML格式,并只编写一(1)条progam处理路径,而不是我们现在必须维护的四(4)条。此外,翻译应该易于反序列化

无论如何,这里是一个输入文件的公平示例:

<?xml version="1.0" encoding="utf-8"?>
<PackageName TransmissionID="0792d49a-c09b-4094-9f4e-2357a042865c">
  <Version>1.0</Version>
  <DateReported>04/12/2010</DateReported>
  <TimeReported>10:16:46.9385105</TimeReported>
  <!-- Status=Disposition -->
  <ReportPackage Status="Disposition1">
    <Addresses>
      <Address>
        <!-- PersonAddress -->
        <Name>Stephen Stipulate</Name>
        <Address>1200 Any Street</Address>
        <City>Some City</City>
        <State>XX</State>
        <Zip>12345</Zip>
        <Phone>800-555-1212</Phone>
      </Address>
    </Addresses>
    <Parts packageID="APackageId">
      <packageClientAccount>00000000</packageClientAccount>
      <DiscardedIdentifier id="NothingOfInterest">
        <AssemblyId>
          <IdValue>0547224801-0908</IdValue>
        </AssemblyId>
        <!-- Status -->
        <AssemblyStatus>
          <Status>OutOfStock</Status>
          <DateReOrderReceived>2009-09-24T06:09:00</DateReOrderReceived>
        </AssemblyStatus>
        <PartVendor>
          <!-- VendorAddress -->
          <VendorName>Roger Refactor</VendorName>
          <VendorAddress>
            <IdValue name="Address">100 An Avenue Suite 13</IdValue>
            <IdValue name="City">A Different City</IdValue>
            <IdValue name="State">YY</IdValue>
            <IdValue name="Zip">54321</IdValue>
            <IdValue name="Phone">866-555-1212</IdValue>
          </VendorAddress>
        </PartVendor>
        <PartsMainSegment>
          <AdditionalSegment>
            <PartSpecs>
              <Spec>
                <PartId>123456</PartId>
                <Name>Widget1</Name>
                <ThresholdLevel>000500</ThresholdLevel>
              </Spec>
              <Spec>
                <PartId>234567</PartId>
                <Name>Widget2</Name>
                <ThresholdLevel>000200</ThresholdLevel>
              </Spec>
            </PartSpecs>
          </AdditionalSegment>
        </PartsMainSegment>
        <AdditionallPartsSegment>
          <Spec>
            <PartId>123456</PartId>
            <PartType>ABC</PartType>
          </Spec>
          <Spec>
            <PartId>234567</PartId>
            <PartType>CBA</PartType>
          </Spec>
        </AdditionallPartsSegment>
        <AdditionalItems type="RawData" qualifier="mode" vendor="rogerRefactor">
          <Text>AModeValue</Text>
        </AdditionalItems>
        <AdditionalItems type="RawData" qualifier="indicator" vendor="rogerRefactor">
          <Text>AnIndicator</Text>
        </AdditionalItems>
      </DiscardedIdentifier>
    </Parts>
  </ReportPackage>
</PackageName>

1
04/12/2010
10:16:46.9385105
斯蒂芬规定
任何街道1200号
某市
XX
12345
800-555-1212
00000000
0547224801-0908
缺货
2009-09-24T06:09:00
罗杰重构
安安大道100号13套房
不同的城市
YY
54321
866-555-1212
123456
Widget1
000500
234567
Widget2
000200
123456
基础知识
234567
中国篮球协会
贬值
指示器
以及所需的输出文件:

<?xml version="1.0" encoding="utf-8"?>
<Package>
  <TransmissionID>0792d49a-c09b-4094-9f4e-2357a042865c</TransmissionID>
  <PackageType>PackageName</PackageType>
  <Version>1.0</Version>
  <DateReported>1/03/2011</DateReported>
  <TimeReported>16:25:35.1293170</TimeReported>
  <Disposition>Disposition1</Disposition>>
  <packageID>APackageId</packageID>
  <packageClientAccount>00000000</packageClientAccount>
  <Addresses>
    <PersonAddress>
      <Name>Stephen Stipulate</Name>
      <Address>1200 Any Street</Address>
      <City>Some City</City>
      <State>XX</State>
      <Zip>12345</Zip>
      <Phone>800-555-1212</Phone>
    </PersonAddress>
    <VendorAddress>
      <Name>Roger Refactor</Name>
      <Address>100 An Avenue Suite 13</Address>
      <City>A Different City</City>
      <State>YY</State>
      <Zip>54321</Zip>
      <Phone>866-555-1212</Phone>
    </VendorAddress>
  </Addresses>
  <Parts>
    <AssemblyId id="0547224801-0908">
      <Status>OutOfStock</Status>
      <DateReOrderReceived>2009-09-24T06:09:00</DateReOrderReceived>
      <Part>
        <PartId>123456</PartId>
        <PartName>Widget1</PartName>
        <Level>000500</Level>
        <PartType>ABC</PartType>
      </Part>
      <Part>
        <PartId>234567</PartId>
        <PartNameName>Widget2</PartNameName>
        <Level>000200</Level>
        <PartType>CBA</PartType>
      </Part>
    </AssemblyId>
  </Parts>
  <AdditionalData>
    <Vendor>TheVendor</Vendor>
    <Mode>AModeValue</Mode>
    <Indicator>AnIndicator</Indicator>
  </AdditionalData>
</Package>

0792d49a-c09b-4094-9f4e-2357a042865c
包装名称
1
1/03/2011
16:25:35.1293170
性格1>
APackageId
00000000
斯蒂芬规定
任何街道1200号
某市
XX
12345
800-555-1212
罗杰重构
安安大道100号13套房
不同的城市
YY
54321
866-555-1212
缺货
2009-09-24T06:09:00
123456
Widget1
000500
基础知识
234567
Widget2
000200
中国篮球协会
卖主
贬值
指示器
我们实际上得到了类似于向web服务报告的XML。请注意所需的重新命名,将数据移动到树的不同部分,尤其是必须连接的不同段,以形成没有父/子关系的零件记录列表。我没有提供任何不好的开始尝试,因为我不知道从哪里开始,因为我根本不知道如何安排处理顺序,而且我确信有人(Dimitre!),虽然不是故意的,但会让我看起来像个白痴!:)


好的,谢谢你的帮助——干杯

像这样的东西其实很简单,主要是编写一个模板并使用XPath选择器从XML树中提取信息

目前尚不清楚某些项目是否会出现多次,例如,
VendorAddress
,但这种转换至少可以从您提供的输入中创建所需的输出

Package/AdditionalData/Vendor
有问题,正如您所说,您想要的值是
TheVendor
,但此字符串不显示在源数据中。我从
PartVendor/VendorName
中提取了它。也没有任何东西可以将该名称与
AdditionalItems
vendor=“rogerRefactor”
属性联系起来,但我相信您会对这些内容进行排序

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

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/PackageName">
        <Package>
            <TransmissionID><xsl:value-of select="@TransmissionID"/></TransmissionID>
            <PackageType>PackageName</PackageType>
            <xsl:copy-of select="Version"/>
            <xsl:copy-of select="DateReported"/>
            <xsl:copy-of select="TimeReported"/>
            <Disposition><xsl:value-of select="ReportPackage/@Status"/></Disposition>
            <packageID><xsl:value-of select="ReportPackage/Parts/@packageID"/></packageID>
            <packageClientAccount><xsl:value-of select="ReportPackage/Parts/packageClientAccount"/></packageClientAccount>
            <Addresses>
                <PersonAddress>
                    <xsl:apply-templates select="ReportPackage/Addresses/Address"/>
                </PersonAddress>
                <VendorAddress>
                    <xsl:apply-templates select="ReportPackage/Parts//PartVendor"/>
                </VendorAddress>
            </Addresses>
            <xsl:apply-templates select="ReportPackage/Parts"/>
            <AdditionalData>
                <Vendor><xsl:value-of select=".//PartVendor/VendorName"/></Vendor>
                <Mode><xsl:value-of select=".//AdditionalItems[@qualifier='mode']/Text"/></Mode>
                <Indicator><xsl:value-of select=".//AdditionalItems[@qualifier='indicator']/Text"/></Indicator>
            </AdditionalData>
        </Package>
    </xsl:template>

    <xsl:template match="Parts">
        <Parts>
            <AssemblyId>
                <xsl:attribute name="id">
                    <xsl:value-of select=".//AssemblyId/IdValue"/>
                </xsl:attribute>
                <Status><xsl:value-of select=".//AssemblyStatus/Status"/></Status>
                <DateReOrderReceived><xsl:value-of select=".//AssemblyStatus/DateReOrderReceived"/></DateReOrderReceived>
                <xsl:for-each select=".//PartsMainSegment/AdditionalSegment/PartSpecs/Spec">
                    <Part>
                        <xsl:variable name="part-id" select="PartId"/>
                        <PartId><xsl:value-of select="PartId"/></PartId>
                        <PartName><xsl:value-of select="Name"/></PartName>
                        <Level><xsl:value-of select="ThresholdLevel"/></Level>
                        <PartType><xsl:value-of select="//AdditionallPartsSegment/Spec[PartId = $part-id]/PartType"/></PartType>
                    </Part>
                </xsl:for-each>
            </AssemblyId>
        </Parts>
    </xsl:template>

    <xsl:template match="Address">
        <Name><xsl:value-of select="Name"/></Name>
        <Address><xsl:value-of select="Address"/></Address>
        <City><xsl:value-of select="City"/></City>
        <State><xsl:value-of select="State"/></State>
        <Zip><xsl:value-of select="Zip"/></Zip>
        <Phone><xsl:value-of select="Phone"/></Phone>
    </xsl:template>

    <xsl:template match="PartVendor">
        <Name><xsl:value-of select="VendorName"/></Name>
        <Address><xsl:value-of select="VendorAddress/IdValue[@name='Address']"/></Address>
        <City><xsl:value-of select="VendorAddress/IdValue[@name='City']"/></City>
        <State><xsl:value-of select="VendorAddress/IdValue[@name='State']"/></State>
        <Zip><xsl:value-of select="VendorAddress/IdValue[@name='Zip']"/></Zip>
        <Phone><xsl:value-of select="VendorAddress/IdValue[@name='Phone']"/></Phone>
    </xsl:template>

</xsl:stylesheet>

包装名称
输出

<?xml version="1.0" encoding="UTF-8"?>
<Package>
   <TransmissionID>0792d49a-c09b-4094-9f4e-2357a042865c</TransmissionID>
   <PackageType>PackageName</PackageType>
   <Version>1.0</Version>
   <DateReported>04/12/2010</DateReported>
   <TimeReported>10:16:46.9385105</TimeReported>
   <Disposition>Disposition1</Disposition>
   <packageID>APackageId</packageID>
   <packageClientAccount>00000000</packageClientAccount>
   <Addresses>
      <PersonAddress>
         <Name>Stephen Stipulate</Name>
         <Address>1200 Any Street</Address>
         <City>Some City</City>
         <State>XX</State>
         <Zip>12345</Zip>
         <Phone>800-555-1212</Phone>
      </PersonAddress>
      <VendorAddress>
         <Name>Roger Refactor</Name>
         <Address>100 An Avenue Suite 13</Address>
         <City>A Different City</City>
         <State>YY</State>
         <Zip>54321</Zip>
         <Phone>866-555-1212</Phone>
      </VendorAddress>
   </Addresses>
   <Parts>
      <AssemblyId id="0547224801-0908">
         <Status>OutOfStock</Status>
         <DateReOrderReceived>2009-09-24T06:09:00</DateReOrderReceived>
         <Part>
            <PartId>123456</PartId>
            <PartName>Widget1</PartName>
            <Level>000500</Level>
            <PartType>ABC</PartType>
         </Part>
         <Part>
            <PartId>234567</PartId>
            <PartName>Widget2</PartName>
            <Level>000200</Level>
            <PartType>CBA</PartType>
         </Part>
      </AssemblyId>
   </Parts>
   <AdditionalData>
      <Vendor>Roger Refactor</Vendor>
      <Mode>AModeValue</Mode>
      <Indicator>AnIndicator</Indicator>
   </AdditionalData>
</Package>

0792d49a-c09b-4094-9f4e-2357a042865c
包装名称
1
04/12/2010
10:16:46.9385105
性格1
APackageId
00000000
斯蒂芬规定
任何街道1200号
某市
XX
12345
800-555-1212
罗杰重构
安安大道100号13套房
不同的城市
YY
54321
866-555-1212
缺货
2009-09-24T06:09:00
123456
Widget1
000500
基础知识
234567
Widget2
000200
中国篮球协会
罗杰重构
贬值
指示器

我们能否假设输入文件中的元素始终与示例中的顺序相同?另外,XSLT2.0是一种可能性,还是您一直坚持使用1.0?是的,它们的顺序总是一样的