How to traverse after disable-output-escaping

耗尽温柔 提交于 2019-12-12 03:04:52

问题


I have a XML like this -

<DOCUMENT>
<SERVICE>
<ID>1338</ID>
<NAME>
&lt;EN&gt;this is an english name&lt;/EN&gt;
&lt;DE&gt;this is a german name&lt;/DE&gt;
</NAME>
</SERVICE>
</DOCUMENT>

As you can see the elements inside the name tag are XML like but not really formatted as elements. The output XML needs to look like

<SERVICES>
<SERVICE ID="1338" EN="this is an english name" DE="this is a german name"/>
</SERVICES> 

I am trying to get the value of the EN and DE through XPATH. I have tried to playaround with disable-output-escaping but I dont think that will work.

<xsl:template match="/">
<SERVICES>
<SERVICE>
<xsl:attribute name="ID"><xsl:value-of select="DOCUMENT/SERVICE/ID"/></xsl:attribute>
<xsl:attribute name="EN"><xsl:value-of select="DOCUMENT/SERVICE/NAME/EN" disable-output-escaping="yes"/></xsl:attribute>
<xsl:attribute name="DE"><xsl:value-of select="DOCUMENT/SERVICE/NAME/DE" disable-output-escaping="yes"/></xsl:attribute>
</SERVICE>
</SERVICES>
</xsl:template>

Any suggestions here?


回答1:


The preferred approach is to take the string content of the NAME element and put it through an XML parser to turn it into a node tree. This can be done if your processor supports an extension such as saxon:parse() (or XPath 3.0 parse-xml()), or by calling out to an extension function.

If the internal XML is very stereotyped and predictable, then you could perhaps parse it by direct string manipulation.




回答2:


If you are able to use XSLT 2.0, take advantage of some of their parsing functions. You could use analyze-string to pull out the data that you need.

Below should be a full working transformation.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <DOCUMENT>
            <SERVICES>
                <xsl:for-each select="DOCUMENT/SERVICE">
                    <SERVICE>
                        <xsl:attribute name="ID"><xsl:value-of select="ID"/></xsl:attribute>
                        <xsl:analyze-string select="NAME" regex="&lt;(.*?)&gt;(.*?)&lt;/\1&gt;">
                            <xsl:matching-substring>
                                <xsl:attribute name="{regex-group(1)}" select="regex-group(2)"/>
                            </xsl:matching-substring>
                        </xsl:analyze-string>
                    </SERVICE>
                </xsl:for-each>
            </SERVICES>
        </DOCUMENT>
    </xsl:template>
</xsl:stylesheet>


来源:https://stackoverflow.com/questions/15276930/how-to-traverse-after-disable-output-escaping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!