Извлечение XML из XML, упакованного в SOAP, с помощью XSLT

Я использовал XSLT в течение нескольких лет, но никогда не сталкивался с XML-файлом, заключенным в SOAP.

Мне нужно изменить сообщение XML с помощью приведенного ниже XSLT, чтобы извлечь некоторые определенные элементы, а не все тело в новый файл XML. Я объявил пространства имен, но независимо от того, как я настроил совпадение xsl:template, я не могу ссылаться ни на что в элементе Batch.

Может ли кто-нибудь указать мне в правильном направлении, пожалуйста.

Сократить XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:header>
    <div:delivery xmlns:div="http://schemas.biztalk.org/btf-2-0/delivery" SOAP-    ENV:mustUnderstand="1">
    <div:message>
    <div:messageID></div:messageID>
    </div:message>
    <div:to>
    <div:address></div:address>
    </div:to>
    <div:from>
        <div:address></div:address>
    </div:from>
    </div:delivery>
    <prop:properties xmlns:prop="http://schemas.biztalk.org/btf-2-0/properties" SOAP-ENV:mustUnderstand="1">
    <prop:identity>00000000</prop:identity>
    <prop:sentAt>2012-06-27T20:00:57</prop:sentAt>
    <prop:expiresAt>2010-01-01T00:00:00</prop:expiresAt>
    <prop:topic>BBAINV</prop:topic>
    </prop:properties>
</SOAP-ENV:header>
<SOAP-ENV:body>
<Batch xmlns="urn:schemas-basda-org:BatchEnvelope" DocType="Invoice" SupplierName="76787980" Number="2" Date="2012-06-27">
<Invoice>
<InvoiceHead>
<Schema>
<Version>3.09</Version>
</Schema>
<Stylesheet>
<StylesheetOwner>BASDA</StylesheetOwner>
<StylesheetName>eBIS-XML_simple.xsl</StylesheetName>
<Version>1</Version>
<StylesheetType>XSL</StylesheetType>
<LogoURL>http://www.someone.co.uk/stylesheets/invoices.xsl</LogoURL>
</Stylesheet>
<Parameters>
<Language>en-GB</Language>
<DecimalSeparator>.</DecimalSeparator>
<Precision>20.4</Precision>
</Parameters>
<OriginatingSoftware>
<SoftwareManufacturer></SoftwareManufacturer>
<SoftwareProduct></SoftwareProduct>
<SoftwareVersion></SoftwareVersion>
<SoftwareSystemID></SoftwareSystemID>
</OriginatingSoftware>
<TestFlag TestReference="">
<Test ExpectedReply="" Mode=""></Test>
</TestFlag>
<InvoiceType Code="INV" Codelist="99">INVOICE</InvoiceType>
<Function Code="" Codelist="" Preserve=""></Function>
<InvoiceCurrency>
<Currency Code="GBP" Codelist="">GBP</Currency>
<AlternateCurrency Code="" Codelist=""></AlternateCurrency>
<Rate CalculationType=""></Rate>
</InvoiceCurrency>
<Intrastat>
<CommodityCode></CommodityCode>
<CommodityDescription></CommodityDescription>
<NatureOfTransaction Code="" Codelist=""></NatureOfTransaction>
<SupplementaryUnits></SupplementaryUnits>
<CountryOfDestination Code="" Codelist=""></CountryOfDestination>
<ModeOfTransport Code="" Codelist=""></ModeOfTransport>
</Intrastat>
<Checksum></Checksum>
</InvoiceHead>
<InvoiceReferences>
<ContractOrderReference>1499001</ContractOrderReference>
<CostCentre>999925/1</CostCentre>
<BuyersOrderNumber Preserve="">22111366</BuyersOrderNumber>
<Department></Department>
<GeneralLedgerCode></GeneralLedgerCode>
<ProjectCode Preserve="true">SH146597</ProjectCode>
<ProjectAnalysisCode Preserve="true">101999</ProjectAnalysisCode>
<SuppliersInvoiceNumber Preserve="true">10011999</SuppliersInvoiceNumber>
<DeliveryNoteNumber>SH 22925/1</DeliveryNoteNumber>
<SuppliersOrderReference Preserve="">SH 111925</SuppliersOrderReference>
<ResponseTo></ResponseTo>
<BatchNumber></BatchNumber>
<GloballyUniqueID Preserve=""></GloballyUniqueID>
</InvoiceReferences>
</Invoice>
</Batch>

Полная таблица стилей

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:b="urn:schemas-basda-org:BatchEnvelope">

<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes" indent="yes"/>

<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>

<!-- *******************************************************************************-->
<xsl:template match="/">
    <xsl:apply-templates select="b:Batch"/>
</xsl:template>

<xsl:template match="/b:Batch">
    <Batch>
    <xsl:value-of select="$newline"/><!-- Put in a line break -->
    <xsl:for-each select="b:Invoice">
    <Invoice>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <InvoiceHead>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceHead/InvoiceType"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </InvoiceHead>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="TaxPointDate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="OriginalOrderDate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <InvoiceReferences>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="InvoiceReferences/DeliveryNoteNumber"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="InvoiceReferences/SuppliersOrderReference"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="InvoiceReferences/BuyersOrderNumber"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="InvoiceReferences/SuppliersInvoiceNumber"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </InvoiceReferences>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceDate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <Supplier>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <SupplierReferences>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Supplier/SupplierReferences/BuyersCodeForSupplier"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </SupplierReferences>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </Supplier>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <Buyer>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <BuyerReferences>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Buyer/BuyerReferences/Organisation"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </BuyerReferences>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="Buyer/Party"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="Buyer/Address"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <Contact>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Buyer/Contact/DDI"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </Contact>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </Buyer>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <Delivery>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <DeliverTo>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Delivery/DeliverTo/Address"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </DeliverTo>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="Delivery/DeliveryInformation"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <DeliverFrom>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <DeliverFromReferences>
                    <xsl:value-of select="$newline"/><!-- Put in a line break -->
                    <xsl:copy-of select="Delivery/DeliverFrom/DeliverFromReferences/SuppliersCodeForLocation"/>
                    <xsl:value-of select="$newline"/><!-- Put in a line break -->
                </DeliverFromReferences>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Delivery/DeliverFrom/Party"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Delivery/DeliverFrom/Address"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <Contact>
                    <xsl:value-of select="$newline"/><!-- Put in a line break -->
                    <xsl:copy-of select="Delivery/DeliverFrom/Contact/DDI"/>
                    <xsl:value-of select="$newline"/><!-- Put in a line break -->
                    <xsl:copy-of select="Delivery/DeliverFrom/Contact/Fax"/>
                    <xsl:value-of select="$newline"/><!-- Put in a line break -->
                </Contact>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </DeliverFrom>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </Delivery>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:for-each select="InvoiceLine">
        <InvoiceLine>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <Product>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Product/SuppliersProductCode"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Product/Description"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </Product>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="Narrative"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <Quantity>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Quantity/Amount"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </Quantity>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="Quantity"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="GrossLineTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <Price>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Price/UnitPrice"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="Price/SpecialPriceDescription"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </Price>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceLineInformation"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <LineTax>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="LineTax/TaxRate"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
                <xsl:copy-of select="LineTax/TaxValue"/>
                <xsl:value-of select="$newline"/><!-- Put in a line break -->
            </LineTax>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="LineTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </InvoiceLine>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </xsl:for-each>

        <xsl:copy-of select="Narrative"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <TaxSubTotal>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="TaxSubTotal/TaxRate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="TaxSubTotal/NumberOfLinesAtRate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="TaxSubTotal/TaxableValueAtRate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->       
            <xsl:copy-of select="TaxSubTotal/TaxAtRate"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </TaxSubTotal>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <InvoiceTotal>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/NumberOfLines"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/NumberOfTaxRates"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/FreightCharges"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/LineValueTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/TaxableTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/TaxableTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/TaxTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
            <xsl:copy-of select="InvoiceTotal/GrossPaymentTotal"/>
            <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </InvoiceTotal>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
    </Invoice>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        </xsl:for-each>
    <TaxBatchTrailer>   
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/TaxRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/TotalValueAtRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/TaxableValueAtRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/TaxAtRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/NetPaymentAtRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="TaxBatchTrailer/GrossPaymentAtRate"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
    </TaxBatchTrailer>
    <xsl:value-of select="$newline"/><!-- Put in a line break -->
    <BatchTrailer>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/TotalNumberOfItems"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/TotalValue"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/TaxableTotal"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/TaxTotal"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/NetPaymentTotal"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
        <xsl:copy-of select="BatchTrailer/GrossPaymentTotal"/>
        <xsl:value-of select="$newline"/><!-- Put in a line break -->
    </BatchTrailer>
    <xsl:value-of select="$newline"/><!-- Put in a line break -->
</Batch>
<xsl:value-of select="$newline"/><!-- Put in a line break -->
</xsl:template>
</xsl:stylesheet>

person Simonhi99    schedule 03.08.2012    source источник
comment
d:Batch != b:Batch -- это опечатка?   -  person Jim Garrison    schedule 03.08.2012


Ответы (1)


Как упомянул Джим Гаррисон, у вас есть d:batch (т.е. вы используете префикс 'd', который не был объявлен, вместо 'b') в какой-то момент. Это было бы фатальной ошибкой, так что, по-видимому, в вашей неурезанной таблице стилей этого нет?

Другая проблема, которая может помешать сопоставлению элемента Batch, заключается в том, что вы запрашиваете элемент верхнего уровня «/b:Batch», тогда как в образце ввода <Batch> не является элементом верхнего уровня. Но опять же, возможно, это разница между урезанным XSLT и вашей настоящей таблицей стилей. (Пожалуйста, убедитесь, что ваш урезанный образец хорошо соответствует действительности!)

Если вам действительно удалось получить доступ к <Batch>, но не удалось получить доступ к элементам, которые являются потомками <Batch>, проблема в том, что вы не обращаетесь к этим элементам в их пространстве имен.

Объявление пространства имен по умолчанию xmlns="..." для <Batch> наследуется всеми его потомками (пока не будет переопределено). Следовательно, любой потомок (например, <Invoice>), у которого нет префикса пространства имен, находится в том же пространстве имен по умолчанию, "urn:schemas-basda...". Итак, вместо

<xsl:for-each select="Invoice">

вам понадобится

<xsl:for-each select="b:Invoice">

ХТН.

person LarsH    schedule 03.08.2012
comment
Спасибо за комментарии, опечатка в XSLT была моей ошибкой, поэтому я добавил полный системный лист, образец XML точен. Если я изменю строку на ‹xsl:for-each select=b:Invoice›, я все равно не получу никакого вывода. Поэтому я предполагаю, что я все еще не обращаюсь к правильным потомкам :( - person Simonhi99; 06.08.2012
comment
@ Simonhi99, см. 2-й абзац моего ответа. Таблица стилей по-прежнему не будет работать, потому что вы пытаетесь применить шаблоны к "/b:Batch", то есть к элементу верхнего уровня, а <Batch> на верхнем уровне нет. Измените свои первые шаблоны применения на select="//b:Batch" и измените шаблон соответствия второго шаблона на match="b:Batch" (без косой черты). - person LarsH; 06.08.2012