从包含xml的字符串中提取节点

时间:2011-01-26 04:28:36

标签: c# asp.net xml xslt

我正在使用Web服务并获取SOAP信封,我试图提取一些数据,但不断遇到错误。我尝试过LINQ,使用xsl转换等等。

回复是:

<?xml version="1.0" encoding="utf-8" ?> 
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <soap:Body>
- <ABRSearchByABNResponse xmlns="some service /">
- <ABRPayloadSearchResults>
- <request>
- <identifierSearchRequest>
  <authenticationGUID>some guid</authenticationGUID> 
  <identifierType>ABN</identifierType> 
  <identifierValue>54 108 408 566</identifierValue> 
  <history>N</history> 
  </identifierSearchRequest>
  </request>
- <response>
  <usageStatement>some statementusageStatement> 
  <dateRegisterLastUpdated>2011-01-26</dateRegisterLastUpdated> 
  <dateTimeRetrieved>2011-01-26T15:14:45.9776800+11:00</dateTimeRetrieved> 
- <businessEntity>
  <recordLastUpdatedDate>2000-08-26</recordLastUpdatedDate> 
- <ABN>
  <identifierValue>11111111111</identifierValue> 
  <isCurrentIndicator>Y</isCurrentIndicator> 
  <replacedIdentifierValue xsi:nil="true" /> 
  <replacedFrom>0001-01-01</replacedFrom> 
  </ABN>
- <entityStatus>
  <entityStatusCode>Active</entityStatusCode> 
  <effectiveFrom>2000-06-05</effectiveFrom> 
  <effectiveTo>0001-01-01</effectiveTo> 
  </entityStatus>
  <ASICNumber /> 
- <entityType>
  <entityTypeCode>IND</entityTypeCode> 
  <entityDescription>Individual/Sole Trader</entityDescription> 
  </entityType>
- <goodsAndServicesTax>
  <effectiveFrom>2000-07-01</effectiveFrom> 
  <effectiveTo>0001-01-01</effectiveTo> 
  </goodsAndServicesTax>
- <legalName>
  <givenName>some name</givenName> 
  <otherGivenName /> 
  <familyName>some name</familyName> 
  <effectiveFrom>2000-08-26</effectiveFrom> 
  <effectiveTo>0001-01-01</effectiveTo> 
  </legalName>
- <mainBusinessPhysicalAddress>
  <stateCode>QLD</stateCode> 
  <postcode>4350</postcode> 
  <effectiveFrom>2000-08-26</effectiveFrom> 
  <effectiveTo>0001-01-01</effectiveTo> 
  </mainBusinessPhysicalAddress>
  </businessEntity>
  </response>
  </ABRPayloadSearchResults>
  </ABRSearchByABNResponse>
  </soap:Body>
  </soap:Envelope>

我的xslt文件:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:soap="http://soap/Envelope/Body/">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">
      <table>
        <tr>
          <th>Name</th>
        </tr>
        <xsl:for-each select="soap/ABRSearchByABNResponse/ABRPayloadSearchResults/response/businessEntity/legalName">
          <tr>
            <td>
              <xsl:value-of select="givenName"/>
            </td>      
          </tr>   
      </xsl:for-each>

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

在我的代码背后,我尝试过:

XmlTextReader reader = new XmlTextReader(new StringReader(searchPayload));
string XslPath = @"http://localhost:5434/SearchResult.xslt";
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(XslPath);
transform.Transform(reader, null, Response.Output);

但名称为空,我也尝试了

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(new StringReader(searchPayload));

XmlNodeList xnList = xmlDoc.SelectNodes("/soap:Envelope/soap:Body/ABRSearchByABNResponse/ABRPayloadSearchResults/request/response/businessEntity/ABN");
foreach(XmlNode xn in xnList)
{
    string abn = xn["identifierValue"].InnerText;
    label1.Text = abn;
}

然后我得到“需要命名空间管理器或XsltContext。此查询具有前缀,变量或用户定义的函数。”等等。

编辑: 所以现在我使用(searchPayload是包含xml响应的字符串)

XDocument doc = XDocument.Load(new StringReader(searchPayload));
XNamespace ns = @"http://abr.business.gov.au/ABRXMLSearch/";

var ABN = doc.Descendants(ns + "businessEntity")
             .Elements(ns + "ABN")
             .Select(node => new
             {
                 identifierValue = node.Element(ns + "identifierValue").Value,
                 isCurrentIndicator = node.Element(ns + "isCurrentIndicator").Value,
                 replacedIdentifierValue = node.Element(ns + "replacedIdentifierValue").Value,
                 replacedFrom = node.Element(ns + "replacedFrom").Value
             }).ToList();

如何从此处获取ABN,例如文本框?

`label1.Text = ABN.ToString();` gives me
Results:System.Collections.Generic.List`1[<>f__AnonymousType0`4[System.String,System.String,System.String,System.String]]

EDIT2: 我现在意识到我能做到:

foreach(var item in ABN)
{
    label1.Text += item.identifierValue.ToString();
}

2 个答案:

答案 0 :(得分:2)

@John Saunders是正确的 - 您必须在从XML检索数据时指定命名空间。目前,命名空间在XML中设置:

 <ABRSearchByABNResponse xmlns="some service /">

使用LINQ to XML进行快速验证可以成功检索结果。

XDocument doc = XDocument.Load(@"test.xml");
XNamespace ns = "some service /";

var ABN = doc.Descendants(ns + "businessEntity")
             .Elements(ns + "ABN")
             .Select(node => new
             {
                identifierValue = node.Element(ns + "identifierValue").Value,
                isCurrentIndicator = node.Element(ns + "isCurrentIndicator").Value,
                replacedIdentifierValue = node.Element(ns + "replacedIdentifierValue").Value,
                replacedFrom = node.Element(ns + "replacedFrom").Value
             }).ToList(); 

答案 1 :(得分:1)

ABRSearchByABNResponse元素及其后代位于“some service”命名空间中。