2017-02-21 21 views
1

Например это мой XML-файл:XSLT: Как заменить некоторые имена XML элементов другими

<?xml version="1.0" encoding="UTF-8" ?> 
<products> 
<product> 
    <code>37</code> 
    <ws_code>T37</ws_code> 
    <barcode>11111111</barcode> 
</product> 
</products> 

Я хочу, чтобы изменить его к этому:

<?xml version="1.0" encoding="UTF-8" ?> 
<products> 
<product> 
    <ProductCode>37</ProductCode> 
    <ProductBarcode>11111111</ProductBarcode> 
</product> 
</products> 

Я работаю на XSLT файл (там отсутствуют):

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="product/code"> 
     <ProductCode><xsl:apply-templates select="@*|node()" /></ProductCode> 
    </xsl:template> 
    <xsl:template match="product/barcode"> 
     <ProductBarcode><xsl:apply-templates select="@*|node()" /></ProductBarcode> 
    </xsl:template> 
</xsl:stylesheet> 

на самом деле, файл XML приходит на сервер, и я не могу делать какие-либо изменения в этот файл.

Как я могу изменить эти имена элементов и удалить некоторые теги с помощью XSLT и как я могу связать файлы XSLT и XML?

Имена тегов для изменений:

код -> ProductCode
ws_code -> Должен быть удален
штрих-кода -> ProductBarcode

+0

Это здорово, что вы предоставили наглядный пример входного XML и выход вы хотите. Не могли бы вы также опубликовать XSLT, который вы пробовали? –

+0

'code -> ProductCode' означает' ', удаляя' ws_code' в ' ', затем добавьте шаблон преобразования идентификаторов и внесите другие необходимые изменения с помощью дополнительных шаблонов, следующих за этим подходом. –

+0

Я добавил пример моего xslt-файла на вопрос. Но я не знаю, как подключить файл xslt к xml. –

ответ

0

Ваш XSLT довольно близок к тому, что вы хотите, просто он не удаляет элемент ws_code и может быть немного проще.

Чтобы удалить элемент ws_code, создайте шаблон, который соответствует ему, чтобы ничего не делать.

Учитывая ваш ввод XML, вам не нужно соответствовать product/code или product/barcode. Только code и barcode будут соответствовать этим элементам.

Вы можете использовать <apply-templates/>, а не <xsl:apply-templates select="@*|node()"/> в шаблоне совпадения. Это обработает все дочерние элементы текущего узла: см. Applying Template Rules.

Используя *|@* в шаблоне идентификации вместо node()|@*, он не будет соответствовать текстовым узлам, поэтому пробелы между элементами не будут выводиться. Текст под code и barcode по-прежнему выводится из-за built-in Template Rule для текстовых узлов.

XSLT ниже добивается того, чего вы хотите:

<xsl:template match="*|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="*|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="code"> 
    <ProductCode> 
     <xsl:apply-templates/> 
    </ProductCode> 
</xsl:template> 

<xsl:template match="barcode"> 
    <ProductBarCode> 
     <xsl:apply-templates/> 
    </ProductBarCode> 
</xsl:template> 

<xsl:template match="ws_code"/> 

-1

Применяя следующий XSLT-1.0 файл (я назвал его d.xslt) в ваш вышеуказанный входной файл XML (я назвал его d.xml (

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*" /> 

    <!-- identity template --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ws_code[local-name(..) = 'product']" /> 

    <xsl:template match="product/code"> 
     <ProductCode><xsl:value-of select="text()" /></ProductCode> 
    </xsl:template> 

    <xsl:template match="product/barcode"> 
     <ProductBarcode><xsl:value-of select="text()" /></ProductBarcode> 
    </xsl:template> 

</xsl:stylesheet> 

Я проверил это с помощью следующей команды/XSLTProcessor на Linux/Ubuntu:

xsltproc d.xslt d.xml | xmlindent -f -nbe 

и результат:

<?xml version="1.0"?> 
<products> 
    <product> 
     <ProductCode>37</ProductCode> 
     <ProductBarcode>11111111</ProductBarcode> 
    </product> 
</products> 

по желанию.

код Это делает XSLT заменить code и barcode элементы, которые имеют product узел в качестве родителя с ProductCode и ProductBarcode элементов соответственно. ws_code узлы игнорируются, а игнорируемые пробелами устраняются <xsl:strip-space...>.

+0

Пожалуйста, объясните свое нижестоящее. – zx485

+1

Я не вижу необходимости ограничивать совпадение ссылкой на родителя. И я, конечно, не вижу необходимости ссылаться на родителя так наклонно: если вы действительно хотите сопоставить только «код», чей родитель «продукт» говорит «продукт/код» или «код [родительский :: продукт]». –

+0

@ michael.hor257k: Я изменил свой ответ в соответствии с одним из ваших предложений, но, однако, многие пути ведут в Рим. – zx485