2014-01-08 3 views
1

Я хочу удалить пустые атрибуты из xml, а также разбить его на основе определенного элемента. Я создал два xsl для разделения и удаления пустых атрибутов отдельно, его работоспособность. Но мне нужно объединить эти два xsl, чтобы после удаления пустых атрибутов xml нужно было разделить на основе определенного элемента.Сплит XML и удаление пустых атрибутов с помощью xslt 2.0

RemoveAttribute XSLT:

<xsl:template match="node()|@*">   

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

<xsl:template match="@*[not(normalize-space(.))]"> 

    <xsl:if test="descendant::*/@*[not(normalize-space(.))]"> 
    <xsl:copy /> 
    </xsl:if> 

</xsl:template> 
</xsl:stylesheet> 

Расщепление XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 



    <xsl:template match="/*" > 


    <xsl:result-document href="ure.xml"> 
    <xsl:element name="Employee" > 
     <xsl:attribute name="xsi:schemaLocation">sample.xsd</xsl:attribute> 
     <xsl:copy-of select="/Employee/*"/>   
    </xsl:element> 


</xsl:result-document> 

    </xsl:template> 


    </xsl:stylesheet> 

Входной XML:

<?xml version="1.0" encoding="UTF-8"?> 
    <Enroll> 
    <Department id="x1" name=""> 
     <members id ="" name="lio">ds</members> 
    </Department> 
    <Employee> 
    <address id="s1" no=""></address> 
    <domain id="" no="34"></domain> 
    </Employee> 
    </Enroll> 

output_one XML:

<Department id="x1" name=""> 
     <members id ="" name="lio">ds</members> 
    </Department> 

Ouput + _TWO Xml:

<Employee> 
    <address id="s1" ></address> 
    <domain no="34"></domain> 
    </Employee> 

Вывод должен быть два отдельный файл XML, который должен быть расщепленным XML часть и пустые атрибуты должны быть удалены.

Я пробовал его с помощью шаблонов Apply, include и xml pipelining, но я не мог заставить его работать.

Любая помощь будет очень оценена.

ответ

2

Это должно сделать то, что вы описываете:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    exclude-result-prefixes="xsi"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

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

    <xsl:template match="Employee//@*[not(normalize-space())]" /> 

    <xsl:template match="/*" > 

    <xsl:result-document href="output_one.xml"> 
     <xsl:apply-templates select="Department" /> 
    </xsl:result-document> 

    <xsl:result-document href="output_two.xml"> 
     <xsl:apply-templates select="Employee" /> 
    </xsl:result-document> 

    </xsl:template> 

</xsl:stylesheet> 

При запуске на своем условии ввода, результат:

output_one.xml:

<Department id="x1" name=""> 
    <members id="" name="lio">ds</members> 
</Department> 

output_two.xml:

<Employee> 
    <address id="s1" /> 
    <domain no="34" /> 
</Employee> 
+0

спасибо. Но мне также нужно разделить и на другие элементы, один входной XML-файл должен быть разделен на два отдельных xmls, а также удалить пустые атрибуты. В вышеприведенном xml отдел также должен быть разделен на отдельный xml, и пустые атрибуты должны быть удалены. –

+1

В вашем вопросе вы сказали: «Выход должен быть ** одним xml-файлом **, который должен иметь разделенную часть xml и пустые атрибуты необходимо удалить». а затем предоставил пример с одним элементом «Сотрудник». Если это не тот фактический результат, который вы хотите, можете ли вы предоставить нужный результат? – JLRishe

+0

Спасибо за ваше время JLRishe. Я обновил сообщение с помощью ouput xmls. –

2

Я предоставил альтернативу XProc, так как вы отметили вопрос с помощью XProc. Ниже сохраняет элементы Employee:

<p:declare-step version="1.0" xmlns:p="http://www.w3.org/ns/xproc"> 
    <p:input port="source"/> 
    <p:output port="result"/> 

    <p:delete match="@*[normalize-space(.) = '']"/> 
    <p:filter select="//Employee"/> 
</p:declare-step> 

Вы можете выполнить его с XMLCalabash с помощью командной строки, как:

calabash --input source=in.xml --output result=employee.xml test.xpl 

Это предположить, что существует только один элемент Employee в вашем входе. В противном случае он попытается записать несколько элементов Employee в один файл. Сначала он жаловался, что выходной порт результата не принимает последовательности.

Если вы добавите к нему sequence="true" без каких-либо дальнейших изменений, вы получите не-правильно сформированный XML, например, с помощью XSLT-подхода из JLRishe. Вам нужно будет обернуть последовательность элементов Employee в этом случае с p:wrap-sequence, или использовать p:for-each, и что-то вроде p:store писать отдельные сотрудник на диск ..

Примечание: последний абзац может быть немного немногословным если вы являются новыми для XProc.Дайте мне знать, если мне нужно разработать ..

ADDED:

Если вы хотите сохранить как отдел, и элементы сотрудников с XProc, вы можете использовать следующее:

<p:declare-step version="1.0" xmlns:p="http://www.w3.org/ns/xproc"> 

    <p:input port="source"/> 
    <p:output port="employees"> 
     <p:pipe step="employees" port="result"/> 
    </p:output> 
    <p:output port="departments" primary="true"/> 

    <p:delete match="@*[normalize-space(.) = '']" name="cleaned"/> 

    <p:filter select="//Employee"/> 
    <p:wrap-sequence wrapper="Employees" name="employees"/> 

    <p:filter select="//Department"> 
     <p:input port="source"> 
      <p:pipe step="cleaned" port="result"/> 
     </p:input> 
    </p:filter> 
    <p:wrap-sequence wrapper="Departments"/> 

</p:declare-step> 

Вы можете выполнить его с помощью XMLCalabash с помощью командной строки, например:

calabash --input source=in.xml --output employees=employees.xml --output departments.xml test2.xpl 

Код по-прежнему следует за тем же поток, но выходной порт сотрудников не является первичным и должен быть явно привязан к результату этапа сотрудников. Фильтрация отделов использует явное связывание входного порта, чтобы не принимать результат «служащих» в качестве входных данных, а вместо этого - «очищенный». Все остальные входы и выходы связаны автоматически на основе условных обозначений.

Примечание: Я добавил p:wrap-sequence, чтобы сделать его более надежным. Вы можете удалить их, если вы переместили атрибут имени сотрудников с p:wrap-sequence на p:filter перед ним.

HTH!

Смежные вопросы