我正在研究以各种XML格式提供数据的东西,虽然我可以弄清楚如何解析它的大部分内容,但我对XSLT和XPath知之甚少知道从哪里开始汇总这个多重转换的类型,其中一些数据显然只是查找,一些数据重复,元素必须重命名,一些数据在属性中,一些在值中,模板可能必须按特定顺序处理或用变量调用。我不认为这里有这种类型的例子,如果我们能得到一个,它可能会为人们解决很多问题。
目标是从几个来源获取输入,这些来源以不同的形式提供类似的数据,将它们转换为通用的XML表单,并且只写入一(1)个程序处理路径,而不是我们现在拥有的四(4)个保持。此外,翻译应该很容易反序列化。
无论如何,这是一个INPUT文件的公平示例:
<?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>
所需的OUTPUT文件:
<?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>
我们实际上将XML报告给Web服务。注意所需的重命名,数据移动到树的不同部分,特别是必须连接的不同段,以创建没有父/子关系的部分记录列表。我没有提供任何糟糕的启动尝试,因为我不知道从哪里开始,因为我根本不明白如何对处理进行排序,我确信有人在那里(Dimitre!),而不是故意,会让我看起来像个白痴! :)
非常感谢所有帮助 - 干杯! :)
答案 0 :(得分:2)
这样的东西非常简单,主要是编写单个模板并使用XPath选择器从XML树中提取信息。
目前尚不清楚某些项目是否可以多次出现 - 例如VendorAddress
- 但此变换至少会根据您提供的输入创建所需的输出。
Package/AdditionalData/Vendor
存在问题,因为您说您希望值为TheVendor
,但此字符串不会出现在源数据中。我从PartVendor/VendorName
取而代之。也没有任何内容可以将该名称与vendor="rogerRefactor"
的{{1}}属性联系起来,但我相信您会对这些内容进行排序。
AdditionalItems
<强>输出强>
<?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>