Ich habe XML, die durch XSLT 1.0 umgewandelt werden sollte. Der XML-Ordner "Felder" definiert die Namensreihenfolge für jedes "Row" -Element. So hat MaterialCode in jedem "Row" -Ordner die erste Position, StorageMatCode ist der zweite und "Amount" ist der dritte. Ich muss alle "MaterialCode" -Duplikate entfernen, aber alle "Mengen" in einen. Eingang xml:Wählen Sie eindeutige Knoten und Gesamtmenge von Xml mit xslt 1.0
<Response xmlns="http://www.sample.ru/sample/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<ObjectType>StorageMats</ObjectType>
<Version>1.0.0</Version>
<Fields>
<Field type="decimal">MaterialCode</Field>
<Field type="decimal">StorageMatCode</Field>
<Field type="decimal">Amount</Field>
</Fields>
</Header>
<Body>
<Row>
<FieldValue>475625947</FieldValue>
<FieldValue>456789</FieldValue>
<FieldValue>1000</FieldValue>
</Row>
<Row>
<FieldValue>804685387</FieldValue>
<FieldValue>273456</FieldValue>
<FieldValue>3047</FieldValue>
</Row>
<Row>
<FieldValue>973681347</FieldValue>
<FieldValue>578357</FieldValue>
<FieldValue>2037</FieldValue>
</Row>
<Row>
<FieldValue>804685387</FieldValue>
<FieldValue>273456</FieldValue>
<FieldValue>5000</FieldValue>
</Row>
</Body>
</Response>
Ich möchte diese XML erhalten: in
<xsl:stylesheet version="1.0" xmlns="http://www.sample.ru/sample/BDStorageMats/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/>
<xsl:key match="*[local-name()= 'Response']/*[local-name()= 'Body']/*[local-name()= 'Row']" name="codeDistinct" use="*[local-name()= 'FieldValue'][count(*[local-name()= 'Response']/*[local-name()= 'Header']/*[local-name()= 'Fields']/*[local-name()= 'Field'][.='MaterialCode']/preceding-sibling::*)+1]"/>
<xsl:template match="/">
<BDStorageMats>
<xsl:variable name="amountPosition" select="count(*[local-name()= 'Response']/*[local-name()= 'Header']/*[local-name()= 'Fields']/*[local-name()= 'Field'][.='Amount']/preceding-sibling::*)+1"/>
<xsl:variable name="materialCodePosition" select="count(*[local-name()= 'Response']/*[local-name()= 'Header']/*[local-name()= 'Fields']/*[local-name()= 'Field'][.='MaterialCode']/preceding-sibling::*)+1"/>
<xsl:for-each select="*[local-name()= 'Response']/*[local-name()= 'Body']/*[local-name()= 'Row'][generate-id() = generate-id(key('codeDistinct', *[local-name()= 'FieldValue'][count(*[local-name()= 'Response']/*[local-name()= 'Header']/*[local-name()= 'Fields']/*[local-name()= 'Field'][.='MaterialCode']/preceding-sibling::*)+1]))[1]]">
<xsl:variable name="keyGroup" select="key('codeDistinct', *[local-name()= 'FieldValue'][count(*[local-name()= 'Response']/*[local-name()= 'Header']/*[local-name()= 'Fields']/*[local-name()= 'Field'][.='MaterialCode']/preceding-sibling::*)+1])"/>
<BDStorageMat>
<MaterialCode>
<xsl:value-of select="(*[local-name()= 'FieldValue'])[$materialCodePosition]"/>
</MaterialCode>
<Amount>
<xsl:value-of select="sum($keyGroup/(*[local-name()= 'FieldValue'])[$amountPosition])"/>
</Amount>
</BDStorageMat>
</xsl:for-each>
</BDStorageMats>
</xsl:template>
</xsl:stylesheet>
Und es funktioniert:
<?xml version="1.0" encoding="UTF-8"?>
<BDStorageMats xmlns="http://www.sample.ru/sample/BDStorageMats/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BDStorageMat>
<MaterialCode>475625947</MaterialCode>
<Amount>1000</Amount>
</BDStorageMat>
<BDStorageMat>
<MaterialCode>804685387</MaterialCode>
<Amount>8047</Amount>
</BDStorageMat>
<BDStorageMat>
<MaterialCode>973681347</MaterialCode>
<Amount>2037</Amount>
</BDStorageMat>
</BDStorageMats>
ich diesen XSLT erstellt haben Altova, aber mein System verwendet Apache Xalan Prozessor für XSLT a nd es weigert sich, diese Linie von XSLT:
<Amount>
<xsl:value-of select="sum($keyGroup/(*[local-name()= 'FieldValue']) [$amountPosition])"/>
</Amount>
Gibt es eine andere Art und Weise zu tun, was ich über XSLT 1.0 wollen?