#xml #xslt
#xml #xslt
Вопрос:
Я пытался придумать описательное название … lol…
В любом случае; это, вероятно, просто, но здесь я немного затрудняюсь. У меня есть входные данные, которые мне нужно обработать. Мне нужно сделать это:
- Извлеките «процесс» и все его дочерние элементы.
- Измените все «клиентские» префиксы NS на «fha»
- Добавьте базовое пространство имен к тегу «process» (да, я знаю, что это сложно, но именно этого хочет ресурс, который я потребляю).)
Входной файл
<TOTALRequest-Response-Keys xmlns="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<fha_case_number>2812883060</fha_case_number>
<loan_number>1000006611</loan_number>
<score_dt>2019/01/31 16:23:55</score_dt>
<aus>ZFWF</aus>
<times_enqueued>1</times_enqueued>
<TOTALRequest-Response xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<client:process>
<client:monthly_income/>
<!-- many elements -->
<client:loanapp>
<client:loanapptype>MISMOAUS2.4</client:loanapptype>
<ns1:loanappdata xmlns="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard" xmlns:ns2="http://mismo.org/aus/" xmlns:ns1="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<ns2:LOAN_APPLICATION MISMOVersionID="2.4"/>
<!-- many elements ns1:whatever -->
</ns1:loanappdata>
</client:loanapp>
</client:process>
<client:processResponse/>
</TOTALRequest-Response>
</TOTALRequest-Response-Keys>
Желаемый результат
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<soapenv:Body>
<fha:process xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<fha:monthly_income>
<fha:loanapp>
<fha:loanapptype>MISMOAUS2.4</fha:loanapptype>
<ns1:loanappdata xmlns="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard" xmlns:ns2="http://mismo.org/aus/" xmlns:ns1="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<ns2:LOAN_APPLICATION MISMOVersionID="2.4">
</ns1:loanappdata>
</fha:loanapp>
</fha:process>
</soapenv:Body>
</soapenv:Envelope>
Что у меня на данный момент есть
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:ns1="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
xmlns:ns2="http://mismo.org/aus/">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<soapenv:Body>
<fha:process xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<xsl:copy>
<xsl:copy-of select="/*/*/*:process/child::*"/>
</xsl:copy>
</fha:process>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<!--
<xsl:template match="client:*" name="change_prefix">
<xsl:element name="fha:{local-name()}">
<xsl:apply-templates select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<soapenv:Body>
<xsl:copy>
<xsl:copy-of select="/*/*/child::*"/>
</xsl:copy>
<xsl:apply-templates select="change_prefix" />
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
-->
</xsl:stylesheet>
Я много чего перепробовал, но у меня такое чувство, что я просто швыряю лапшу в стену. 🙁
Ответ №1:
Сработает ли это для вас?
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/fha:TOTALRequest-Response-Keys">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<soapenv:Body>
<xsl:apply-templates select="fha:TOTALRequest-Response/client:process"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="client:*">
<xsl:element name="fha:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Комментарии:
1. Это очень близко. Мне нужно исключить моды для этого фрагмента, хотя: <ns1:loanappdata xmlns=» xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard /… » xmlns:ns2=» mismo.org/aus » xmlns:ns1=» xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard /… «> <ns2:LOAN_APPLICATION MISMOVersionID=»2.4»> </ns1:loanappdata>
2. Что делает первый шаблон?
3. Я думаю, что, возможно, я неправильно понимаю последнюю проблему… Я просто собираюсь отметить вас правильно и сказать СПАСИБО, пока я сортирую мелочи.
4. Не уверен, что вы подразумеваете под «исключить моды». За исключением изменения
client
префикса, все копируется как есть (это то, что делает шаблон преобразования идентификатора).5. Я имел в виду «узлы» … не «моды» — это была просто умная затея с моей стороны. Мой статический образец не соответствовал данным реального теста. Я думал, что преобразование удаляет префиксы из встроенного документа, но у тестовых данных не было префиксов пространства имен во встроенном документе. Один показ позже, и я чувствую себя глупо. 🙂 Ваш образец сработал отлично. Мне просто нужно было добавить объявление пространства имен.
Ответ №2:
Оказывается, мне не нужно было ничего делать со встроенным фрагментом. Конечная точка смогла использовать пространство имен по умолчанию для встроенных документов (Но если кто-то захочет ответить на это, я бы не возражал.)
Единственное изменение, которое мне нужно было внести в ответ Майкла, — это добавить объявление пространства имен в тег «envelope». (Майкл никак не мог знать, что конечному процессу потребуется другое пространство имен.)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:client="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:ns2="http://mismo.org/aus/"
xmlns:ns1="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/fha:TOTALRequest-Response-Keys">
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:f17="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard"
xmlns:fha="http://xmlns.oracle.com/F17CTOTALScorecard/F17CTOTALScorecard/F17CTOTALScorecard">
<soapenv:Body>
<xsl:apply-templates select="fha:TOTALRequest-Response/client:process"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="client:*">
<xsl:element name="fha:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>