XSLT node value comparision

2019-03-07 06:02发布

How Can I compare ip address with reference of family and name. using XSLT file. In Details, I have one xml file which has list of operatorstation nodes with each operator station has its unique information. So By considering first operatorstation node as a master comparing all remaining slave operatorStation information. First need to compare IPAddress by grouping Family & Name which gives result like shown below. So I am looking for starnsform script XSLT which give me result shown below. Please check xml file I am using as input, xml file as I am expecting output result and XSLT file I am working on it.
Please ask question if anyone still not understand.... Input xml file

<?xml version="1.0" encoding="utf-8"?>
<OperatorStationCollection xmlns="http://ACORD.org/Standards/Life/2">
  <OperatorStation><Name>OS01</Name>
    <Nodes>
      <DataNodeBase >
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.3</IPAddress>  
      </DataNodeBase>
    </Nodes>
  </OperatorStation>
  <OperatorStation><Name>OS02</Name>
    <Nodes>
          <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.3</IPAddress>  
          </DataNodeBase>
    </Nodes>
  </OperatorStation>
  <OperatorStation><Name>OS03</Name>
    <Nodes>
          <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.4</IPAddress>  
          </DataNodeBase>
    </Nodes>
  </OperatorStation>
  <OperatorStation><Name>OS04</Name>
    <Nodes>
        <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.4</IPAddress>  
        </DataNodeBase>
    </Nodes>
  </OperatorStation>
</OperatorStationCollection>

Expected OUTPUT:

<?xml version="1.0" encoding="utf-8"?> 
<OperatorStationCollection > 
  <Result > 
    <Family>NetworkSettings</Family> 
    <AdaptorName>Internet</AdaptorName> 
    <os01>111.22.22.3</os01> 
    <os02>Equal</os02> 
    <os03>UnEqual</os03> 
    <os04>UnEqual</os04> 
  </Result > 
</OperatorStationCollection>

Script I am trying to add:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns="http://ACORD.org/Standards/Life/2" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kOperatorStation" match="OperatorStation" use="concat(Family,'#',Name)"/>
<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="/*">
  <xsl:copy>
    <xsl:for-each select="OperatorStation[generate-id() = generate-id(key('kOperatorStation',concat(Family,'#',Name))[1])]" >
      <xsl:copy>
        <xsl:variable name="group" select="key('kOperatorStation',concat(current()/Family,'#',current()/Name))" />
        <xsl:for-each select= "$group" >
          <xsl:if test="position() = 1">
            <xsl:apply-templates select="*[local-name() != 'IPAddress']" />            
          </xsl:if>
        </xsl:for-each>
      </xsl:copy>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

c# code for transform:

XmlReader objXmlReader = XmlReader.Create(@"C:\XMLFile1.xml");
            /*Transform and add arguments*/
            XmlReader xsltTransformReader= XmlReader.Create(@"C:\XSLTFile1.xslt");
            XslCompiledTransform objXslTransform = new XslCompiledTransform();
            objXslTransform.Load(xsltTransformReader);

           XmlWriterSettings settings = new XmlWriterSettings();
        settings.Encoding = Encoding.UTF8;

        /*Do transformation*/
        StringBuilder output = new StringBuilder();
        using (XmlWriter xw = XmlWriter.Create(new StringWriter(output), settings))
            {
                objXslTransform.Transform(objXmlReader, xw);             
                string result = output.ToString();
            }

标签: xslt
1条回答
霸刀☆藐视天下
2楼-- · 2019-03-07 06:49

I think I have finally understood this question.

The following stylesheet will group the OperatorStation elements by the Family and Name elements located inside Nodes/DataNodeBase. Note that there is another Name element that is a direct child of OperatorStation - this is potentially confusing.

For each group, the first IPAddress element is listed and the others are compared to it. The names of these result elements are taken from the values of the (top) Name element (just to add some more confusion...).

Pay special attention to the handling of the namespace declared in the source XML document.

Styleheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://ACORD.org/Standards/Life/2"
exclude-result-prefixes="ns"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="kOperatorStation" match="ns:OperatorStation" use="concat(.//ns:Family, '#', .//ns:DataNodeBase/ns:Name)"/>

<xsl:template match="/">
<OperatorStationCollection>
    <xsl:for-each select="ns:OperatorStationCollection/ns:OperatorStation[generate-id() = generate-id(key('kOperatorStation',concat(.//ns:Family, '#', .//ns:DataNodeBase/ns:Name))[1])]" >
    <Result>
        <Family><xsl:value-of select=".//ns:Family"/></Family>
        <AdaptorName><xsl:value-of select=".//ns:DataNodeBase/ns:Name"/></AdaptorName>

        <xsl:variable name="ip" select=".//ns:IPAddress" />

        <xsl:for-each select="key('kOperatorStation', concat(.//ns:Family, '#', .//ns:DataNodeBase/ns:Name))" >  
                <xsl:element name="{ns:Name}">
                    <xsl:choose>
                        <xsl:when test="position()=1">
                            <xsl:value-of select="$ip"/>
                        </xsl:when>
                        <xsl:when test=".//ns:IPAddress=$ip">
                            <xsl:text>Equal</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>UnEqual</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:element>
        </xsl:for-each>
    </Result> 
    </xsl:for-each>
</OperatorStationCollection>
</xsl:template>
</xsl:stylesheet>

Source XML:

<?xml version="1.0" encoding="utf-8"?>
<OperatorStationCollection xmlns="http://ACORD.org/Standards/Life/2">
    <OperatorStation>
        <Name>OS01</Name>
        <Nodes>
            <DataNodeBase >
                    <Family>NetworkSettings</Family>
                    <Name>Internet</Name>
                    <IPAddress>111.22.22.3</IPAddress>  
            </DataNodeBase>
        </Nodes>
    </OperatorStation>  
    <OperatorStation>
        <Name>OS02</Name>
        <Nodes>
            <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.3</IPAddress>  
            </DataNodeBase>
        </Nodes>
        </OperatorStation>      
        <OperatorStation>
        <Name>OS03</Name>
        <Nodes>
            <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.4</IPAddress>  
            </DataNodeBase>
        </Nodes>
    </OperatorStation>      
    <OperatorStation>
        <Name>OS04</Name>
        <Nodes>
            <DataNodeBase>
                <Family>NetworkSettings</Family>
                <Name>Internet</Name>
                <IPAddress>111.22.22.4</IPAddress>  
            </DataNodeBase>
        </Nodes>
    </OperatorStation>
</OperatorStationCollection>

Result:

<?xml version="1.0" encoding="utf-8"?>
<OperatorStationCollection>
  <Result>
    <Family>NetworkSettings</Family>
    <AdaptorName>Internet</AdaptorName>
    <OS01>111.22.22.3</OS01>
    <OS02>Equal</OS02>
    <OS03>UnEqual</OS03>
    <OS04>UnEqual</OS04>
  </Result>
</OperatorStationCollection>
查看更多
登录 后发表回答