#templates #generics #select #xslt #nodes
Вопрос:
У меня есть несколько XML-файлов в различных форматах, все из которых должны иметь определенный тег, прежде чем он будет передан, поэтому я хочу написать универсальный XSLT, который будет принимать любые входные данные XML и просто добавлять дополнительные теги до и после полезной нагрузки. Например:
Входной XML (пример1)
<?xml version="1.0" encoding="UTF-8"?>
<Order>
<data1>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
</data1>
</Order>
Это также может быть другой XML <Invoice>
-файл или что-то еще.
Требуемая Производительность
<?xml version="1.0" encoding="UTF-8"?>
<soap:envelope>
<soap:body>
<Order>
<data1>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
</data1>
</Order>
</soap:body>
</soap:envelope>
С помощью следующего XSLT мне нужно знать, какой узел поступает (заказ или счет), чтобы соответствовать шаблону, но может ли это быть общим?
<?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"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- I do not want to specify the node here -->
<xsl:template match="Order">
<soap:envelope>
<soap:body>
<xsl:copy-of select="*"/>
</soap:body>
</soap:envelope>
</xsl:template>
</xsl:stylesheet>
Комментарии:
1. поскольку <корень> является динамическим, попробуйте сопоставить сам корень.
Ответ №1:
Вывод, который вы показываете, не является хорошо сформированным XML-документом: вы не можете использовать префикс, не привязав его к пространству имен. Ваш XSLT имеет тот же недостаток и не может быть использован без возникновения ошибки (по крайней мере, с соответствующим процессором).
Я предполагаю, что вы хотите использовать:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<soap:envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:body>
<xsl:copy-of select="."/>
</soap:body>
</soap:envelope>
</xsl:template>
</xsl:stylesheet>
чтобы создать действительное сообщение SOAP:
<?xml version="1.0" encoding="UTF-8"?>
<soap:envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:body>
<Order>
<data1>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
</data1>
</Order>
</soap:body>
</soap:envelope>
Комментарии:
1. Спасибо! да, я пропустил пространство имен в своем исходном сообщении, но это отлично работает. На данный момент не могу проголосовать, но принял ответ.
2. @michael : в чем разница в этом случае, если использовать пространство имен в объявлении таблицы стилей,а не в самом элементе? т. е.
<xsl:stylesheet xmlns:soap="---"
против<soap:envelope xmlns:soap="---"
3. @sspsujit В этом случае не было бы никакой разницы.
Ответ №2:
вам нужно соответствовать root
для этого.
<xsl:template match="/">
<soap:envelope>
<soap:body>
<xsl:copy-of select="."/>
</soap:body>
</soap:envelope>
</xsl:template>